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

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

#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

相关推荐
Jack204 小时前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树6 小时前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2121 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2121 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术1 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦1 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
clint4561 天前
C++进阶(1)——前景提要
c++
用户497863050731 天前
(一)小红的数组操作
算法·编程语言
夜悊1 天前
C++代码示例:进制数简单生成工具
c++