Linux怎么查看系统锁竞争_Linux futex与锁等待分析【性能】
技术百科
冰火之心
发布时间:2026-01-15
浏览: 次 定位Linux锁竞争需综合perf、/proc/PID/stack、ftrace、mtxstat和pstack/gdb:一、perf捕获futex系统调用并统计WAIT次数;二、查/proc/PID/stack确认futex_wait阻塞;三、ftrace跟踪futex_wait/wake路径;四、读/proc/sys/kernel/mtxstat的mutex_contended值;五、pstack/gdb分析pthread_mutex用户态阻塞点。
如果您在排查Linux系统性能瓶颈时怀疑存在锁竞争问题,尤其是线程频繁阻塞于互斥操作,则很可能是futex等待或内核锁争用所致。以下是定位和分析锁竞争状态的具体方法:
一、使用perf工具捕获futex相关事件
perf可直接追踪内核中与futex系统调用相关的调度行为,识别高频率的FUTEX_WAIT/FUTEX_WAKE路径,反映锁争用强度。
1、执行perf record命令捕获futex系统调用事件,持续30秒:
perf record -e 'syscalls:sys_enter_futex' -g -- sleep 30
2、生成火焰图或调用栈报告:
perf script | stackcollapse-perf.pl | flamegraph.pl > futex_flame.svg
3、过滤并统计FUTEX_WAIT调用次数:
perf script | awk '$3 ~ /sys_enter_futex/ && $NF ~ /FUTEX_WAIT/ {count++} END {print "FUTEX_WAIT count:", count}'
二、解析/proc/[pid]/stack与/proc/[pid]/status中的锁状态
每个进程的内核栈快照可暴露当前是否阻塞在futex_wait_queue_me等函数上,/proc/[pid]/status则提供线程锁等待的直观标识。
1、查找处于TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE状态的线程:
ps -eo pid,comm,wchan:20,state,tid --sort=-time | head -20
2、对疑似阻塞线程(state为D或S),查看其内核栈:
cat /proc/PID/stack
3、检查该线程是否停在futex_wait或__x64_sys_futex调用点:
grep -q "futex_wait\|__x64_sys_futex" /proc/PID/stack && echo "thread is futex-blocked"
三、利用ftrace动态跟踪futex关键路径
ftrace提供低开销的内核函数级追踪能力,可精确捕获mutex_lock、mutex_unlock及底层futex_wait/wake的调用链与耗时分布。
1、启用futex相关tracepoint:
echo 1 > /sys/kernel/debug/tracing/events/futex/futex_wait/enable
echo 1 > /sys/kernel/debug/tracing/events/futex/futex_wake/enable
2、启动追踪并限定输出长度:
echo 1 > /sys/kernel/debug/tracing/tracing_on
sleep 10
echo 0 > /sys/kernel/debug/tracing/tracing_on
3、读取原始trace日志并提取关键字段:
cat /sys/kernel/debug/tracing/trace | awk '/futex_wait|futex_wake/ {print $1,$2,$3,$4,$5,$6,$7}' | head -50
四、检查/proc/sys/kernel/mtxstat中的mutex_contended计数
Linux内核自4.12起在某些配置下导出mutex_contended统计值,该值表示因互斥锁不可用而进入内核等待队列的次数,是锁竞争的直接量化指标。
1、确认内核是否启用CONFIG_DEBUG_MUTEXES选项:
zcat /proc/config.gz | grep CONFIG_DEBUG_MUTEXES 2>/dev/null || grep CON

2、若已启用,读取全局锁竞争计数:
cat /proc/sys/kernel/mtxstat 2>/dev/null | grep -o "mutex_contended:[0-9]*"
3、对比不同时间段增长速率:
watch -n 5 'cat /proc/sys/kernel/mtxstat 2>/dev/null | grep mutex_contended'
五、通过pstack与gdb分析用户态pthread_mutex阻塞点
当应用层使用pthread_mutex_t时,glibc通过futex实现阻塞,pstack可快速定位线程是否卡在__lll_lock_wait_private等内部函数,表明已进入内核等待。
1、获取目标进程所有线程的C语言级调用栈:
pstack PID > stack.txt
2、筛选含锁等待特征的栈帧:
grep -A5 -B5 "__lll_lock_wait\|futex_wait\|pthread_mutex_lock" stack.txt
3、对特定线程使用gdb附加并检查mutex结构体状态:
gdb -p TID -ex "p ((pthread_mutex_t*)0xADDR)->__data.__lock" -ex "quit"
# ai
# 尤其是
# 不可用
# 您在
# 很可能
# 可直接
# 工具
# linux
# linux系统
# svg
# 线程
# 栈
# 事件
# NULL
# 结构体
# Thread
# echo
# 卡在
# count
# sort
# print
# 性能瓶颈
# c语言
# 互斥
# 中与
# 停在
# 看其
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Python性能剖析高级教程_cProfileLi
- MySQL 中使用 IF 和 CASE 实现查询字
- Django 密码修改后会话失效的解决方案
- Win10如何备份驱动程序_Win10驱动备份步骤
- php怎么连接数据库_MySQL数据库连接的基础代
- windows 10应用商店区域怎么改_windo
- php修改数据怎么批量改状态_批量更新status
- c++如何打印函数堆栈信息_c++ backtra
- 如何在Golang中实现邮件发送功能_Golang
- php会话怎么开启_session_start函数
- Win11如何设置开机问候语 Win11修改登录界
- Go 中实现 Python urllib.quot
- Win11怎么设置组合键快捷方式_Windows1
- Win10如何更改电脑休眠时间_Windows10
- Windows10怎么卸载预装软件_Windows
- php删除数据怎么清空表_truncate与del
- Win11怎么开启游戏模式_Windows11优化
- Win11如何设置鼠标灵敏度_Win11鼠标灵敏度
- 如何使用Golang实现文件追加操作_向已有文件追
- Win11如何连接Xbox手柄 Win11蓝牙连接
- Mac如何备份到iCloud_Mac桌面与文稿文件
- Win11摄像头无法使用怎么办_Win11相机隐私
- 电脑的“网络和共享中心”去哪了_Windows 1
- Mac的访达(Finder)怎么用_Mac文件管理
- Win11怎么设置默认终端应用_Windows11
- Django 测试数据库表缺失与字段未创建问题的完
- Go语言中slice追加操作的底层共享机制详解
- 如何在Windows上设置闹钟和计时器_系统自带的
- Win10怎么查看内存时序参数_Win10CPU-
- 微信短链接怎么还原php_用浏览器开发者工具抓包获
- Win11如何设置文件关联 Win11修改特定文件
- 如何将文本文件中的竖排字符串转换为横排字符串
- Windows如何查看和管理已安装的字体?(字体文
- 如何在 Pandas 中按元素交集合并两列字符串
- 短链接怎么用php递归还原_多层加密链接的处理法【
- 使用类变量定义字符串常量时如何实现类型安全的 Li
- Windows 10怎么录屏_Windows 10
- Python与MongoDB NoSQL开发实战_
- Windows电脑键盘突然失灵怎么办?(驱动与硬件
- php内存溢出怎么排查_php内存限制调试与优化方
- php下载安装后memory_limit怎么设置_
- Win11怎么开启专注模式_Windows11时钟
- C++ static_cast和dynamic_c
- ACF 教程:如何正确更新嵌套在多层 Group
- Python函数接口稳定性_版本演进解析【指导】
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- 如何使用Golang table-driven f
- Mac电脑如何恢复出厂设置_Mac抹掉数据并重装系
- php8.4新语法match怎么用_php8.4m
- Win11怎么清理C盘下载文件夹_Win11清理下

QQ客服