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

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

#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

相关推荐
203号居民2 小时前
LeetCode hot 100 — 25. K 个一组翻转链表
算法·leetcode·链表
广州灵眸科技有限公司2 小时前
从手动三步到上电即连:4G模组systemd开机自连方案
linux·运维·服务器·开发语言·网络·人工智能·php
深念Y3 小时前
【保姆级教程】Proxmox VE (PVE) 安装 FreeBSD 完整指南
服务器·unix·系统·pve·freebsd·虚拟化平台
ocean21033 小时前
2025-2026年AI算法与模型研发面试高频知识点洞察
人工智能·算法·面试
Nil2083 小时前
leetcode 78子集
数据结构·算法·leetcode
喜欢吃燃面4 小时前
深入 C++ STL:从 unordered_set与unordered_map到底层哈希表的原理与实现
数据结构·c++·散列表
子非鱼a4 小时前
【WEB】[SWPU2019]Web1
java·服务器·前端
en.en..4 小时前
Linux fork() 工作原理
数据结构·算法
FlightYe4 小时前
音视频修炼之基础理论(五):AAC格式与解析
android·linux·c++·音视频·aac
qq_452396234 小时前
第十篇:《eBPF 可观测性:零侵扰的深度内核追踪》
服务器·网络·php