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

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

#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

相关推荐
不会C语言的男孩19 分钟前
C++ Primer Plus 第8章:函数探幽
开发语言·c++
都在酒里19 分钟前
Linux字符设备驱动开发(十):综合实例——I2C传感器 + LED智能控制与进阶指南
linux·运维·服务器·驱动开发·交互
William_wL_23 分钟前
【C++】模板进阶
c++
MC皮蛋侠客7 小时前
Google Test 单元测试指南
c++·单元测试·google test
wanhengidc8 小时前
服务器租用有何优点
运维·服务器·安全·web安全
坤昱8 小时前
cfs调度类深入解刨——最新内核细节分析2
linux·服务器·cfs·cfs调度·eevdf调度·eevdf·kernel 7.1
艾莉丝努力练剑8 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
海市公约8 小时前
Linux核心基础命令与权限管理实战指南
linux·运维·服务器·vim·权限管理·系统监控·命令行
kkeeper~9 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
mixboot10 小时前
Linux 进程工作目录查看利器:pwdx 命令详解
linux·运维·服务器