记录一次上下文切换次数的统计

如果要记录因为获取不到锁而切换线程可以用这个封装的锁替代

#pragma once

#include <mutex>

#include <atomic>

#include <iostream>

#include "logger.h"

class StatisticMutex {

std::mutex mtx;

std::atomic<size_t> contention_count{0}; // 统计竞争次数

public:

void enter() {

// 尝试非阻塞获取,若失败则记录竞争

if (!mtx.try_lock()) {

logInfo("NYX ++1 \n");

contention_count.fetch_add(1, std::memory_order_relaxed);

mtx.lock(); // 阻塞等待

}

}

bool try_lock() {

bool success = mtx.try_lock();

if (!success) {

contention_count.fetch_add(1, std::memory_order_relaxed);

}

return success;

}

void leave() {

mtx.unlock();

}

size_t get_contention_count() const {

return contention_count.load(std::memory_order_relaxed);

}

};

用这个脚本统计线程下线程切换的次数每秒

while true; do cat /proc/9759/status | grep ctxt_switches; sleep 1; done

/proc# while true; do cat /proc/9759/status | grep ctxt_switches; sleep 1; done

voluntary_ctxt_switches: 6384

nonvoluntary_ctxt_switches: 408

voluntary_ctxt_switches: 6393

nonvoluntary_ctxt_switches: 409

voluntary_ctxt_switches: 6403

nonvoluntary_ctxt_switches: 410

主动切换次数大约9次每秒 大概有什么sleep 或者频繁的唤醒并且wait...

strace -e trace=nanosleep,futex,read,write -p 9759

strace: Process 9759 attached

通过strace发现确实有8次sleep 才想起是自己加的调试代码为了信标帧可以更频繁的发送 让手机可以识别

futex(0x2e08ca50, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY) = 0

write(1, "2026-05-07 19:36:21.060491 [97"..., 85) = 85

futex(0x2e12f6b0, FUTEX_WAKE_PRIVATE, 1) = 1

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

write(61, "\252U\220\0\0\0\224\0\200\0\0\0\377\377\377\377\377\3778\257)3DU8\257)3DU \375"..., 151) = 151

nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7ef8bfcfd0) = 0

futex(0x2e08ca50, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, FUTEX_BITSET_MATCH_ANY) = 0

改完之后就是标准的1s一次

while true; do cat /proc/21961/status | grep ctxt_switches; sleep 1; done

voluntary_ctxt_switches: 91

nonvoluntary_ctxt_switches: 3

voluntary_ctxt_switches: 92

nonvoluntary_ctxt_switches: 3

voluntary_ctxt_switches: 93

nonvoluntary_ctxt_switches: 3

相关推荐
草莓熊Lotso3 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
Chenyu_3108 小时前
DPDK、TC 和 XDP:Linux 高性能网络到底在优化什么
linux·服务器·网络·缓存
HPtiger9 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训9 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
DongQiShanRen9 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CCblandy9 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构
丑梨数据10 小时前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
乔旭伟10 小时前
Linux 服务器备份实战:一致性快照、日志归档与恢复演练
linux·运维·服务器
把我格子衫拿来10 小时前
VTK 9.5 与 Qt 6 联合开发:从嵌入三维窗口到可维护的桌面架构
c++·python·qt·vtk·三维可视化
乔旭伟10 小时前
Linux 服务器安全加固实战:SSH、防火墙、补丁与入侵排查
linux·服务器·安全