中文
注册

示例4:锁长期等待

简介

多线程程序,经常存在锁不合理长期占用的问题。本示例主要针对这一问题,通过鲲鹏性能分析工具资源调度功能来观测,建议用户分析业务逻辑将不需要锁的计算移出互斥量加锁操作。

环境准备

  1. 请确认服务器上已安装的操作系统是否为Ubuntu 18.04、CentOS 7.6或openEuler 20.03,GCC版本是否为7.3.0及以上。
  2. 请确认服务器上是否已安装鲲鹏DevKit系统性能分析工具。
  3. 请从GithubGitee下载代码样例,执行以下命令赋予所有用户可读、可写和可执行权限。

    样例代码文件为:pthread_atomic.c、pthread_mutex.c、pthread_mutex_long.c和pthread_mutex_long_mod.c。

    chmod 777 pthread_mutex_long.c pthread_atomic.c pthread_mutex.c pthread_mutex_long_mod.c

锁长期占用检测

  1. 程序准备。
    1. 编译pthread_mutex_long.c并赋予执行文件所有用户可读、可写和可执行权限。
      gcc -g pthread_mutex_long.c -o pthread_mutex_long -lpthread -lm && chmod 777 pthread_mutex_long
    2. 绑核到CPU 0,1,使用后台运行程序,需要确定0-1核上没有其他程序正在绑核运行。nohup命令使得即使退出账户之后会继续运行相应的进程,防止任务中断。
      nohup taskset -c 0-1 ./pthread_mutex_long >>pthread_mutex_long.out 2>&1 &

      程序运行的输出(标准输出(1))将会保存到pthread_mutex_long.out文件,错误信息(2)会重定向到pthread_mutex_long.out文件。

  2. 在程序运行的过程当中,创建系统级全景任务分析当前程序。

    创建系统全景分析任务,并启动分析。

    配置参数如下:

    表1 任务配置参数说明

    参数

    说明

    分析对象

    系统

    分析类型

    全景分析

    采样类型

    全选

    采样时长

    30秒

    采样间隔

    1秒

  3. 查看采集分析结果。
    图1 系统性能(时序图)

    当前有CPU核0,1的使用率偏高,两者相加在100%左右。

  4. 采用进程/线程性能分析,观察消耗CPU资源的进程。

    创建进程/线程分析任务,并启动分析。

    表2 任务配置参数说明

    参数

    说明

    分析对象

    系统

    分析类型

    进程/线程性能分析

    采样时长

    30秒

    采样类型

    全选

    采集线程信息

    开启

  5. 查看采集分析结果。
    图2 进程/线程分析结果总览

    图2中默认排序是按照PID/TID升序排列,为便于观察消耗CPU资源的进程,可点击%CPU列旁边的按钮进行降序排列,如图3所示,显示pthread_mutex_long程序在消耗大量的CPU资源。

    图3 进程/线程分析结果排序
  6. 采用系统资源调度分析,观察pthread_mutex_long程序进程和线程的切换次数及抢占情况。

    创建资源调度分析任务,并启动分析。

    表3 任务配置参数说明

    参数

    说明

    分析对象

    系统

    分析类型

    资源调度分析

    采样时长

    60秒

    其他参数

    默认

  7. 查看采集分析结果。
    图4 冷火焰图

    输入进程名点击搜索框旁的按钮,筛选pthread_mutex_long进程,如图4所示。

  8. “CPU/进程统计”的页签中,查看进程/线程详情。
    图5 CPU/进程统计分析结果

    CPU切换链路频繁极有可能是锁互斥量操作。其中一个线程长期占用锁,导致另一个线程无法得到锁而长期等待。

  9. 结束程序。

    通过jobs -l查看pthread_mutex_long程序运行pid(如果程序尚未结束,可以看到后台运行的程序),通过kill -9结束进程。

    jobs -l
    kill -9 <pthread_mutex_long程序pid>

优化方案

将不需要互斥的操作移到pthread_mutex_unlock()之后。

  1. 程序准备。
    1. 编译pthread_mutex_long_mod.c并赋予执行文件所有用户可读、可写、可执行权限。
      gcc -g pthread_mutex_long_mod.c -o pthread_mutex_long_mod -lpthread -lm && chmod 777 pthread_mutex_long_mod
    2. 绑核到CPU 0,1,使用后台运行程序,需要确定0-1核上没有其他程序正在绑核运行。
      nohup taskset -c 0-1 ./pthread_mutex_long_mod >>pthread_mutex_long_mod.out 2>&1 &

      程序运行的输出(标准输出(1))将会保存到pthread_mutex_long_mod.out文件,错误信息(2)会重定向到pthread_mutex_long_mod.out文件。

  2. 采用系统资源调度分析。

    创建系统资源调度分析任务,并启动分析。

    表4 任务配置参数说明

    参数

    说明

    分析对象

    系统

    分析类型

    资源调度分析

    采样时长

    60秒

    其他参数

    默认

  3. 查看采集分析结果。
    图6 冷火焰图

    输入进程名后单击搜索框旁的按钮,选择pthread_mutex_long_mod,如图6,发现切换次数相较优化前大幅减少。

  4. 切换“CPU/进程统计”页签,查看线程情况。
    图7 CPU/进程统计分析结果

    图7所示,进程切换链路明显减少,线程可以并发运行不需要互斥操作的计算,大幅度提升了计算性能。

  5. 结束样例程序。

    通过jobs -l查看pthread_mutex_long_mod程序运行pid(如果程序尚未结束,可以看到后台运行的程序),通过kill -9结束进程。

    jobs -l
    kill -9 <pthread_mutex_long_mod程序pid>
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词