---
title: 示例3：锁频繁抢占
description: "多线程程序，经常会存在锁频繁抢占问题，锁的争抢会导致CPU的资源浪费，可以基于实际的业务减少公共资源的抢占。本示例主要针对这一问题，通过鲲鹏DevKit系统性能分析工具锁与等待分析功能来观测，建议用户分析业务逻辑减少锁的争抢，例如大锁变小锁，减少线程并发数等。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/profiler/demo/KunpengDevKitDsug_0023.html
sourcePath: /source/zh/kunpengdevps/profiler/demo/KunpengDevKitDsug_0023.html
indexId: 6eb715591cca95a195c555980d9a44988fc6875a0f209b98e537325c1b114a6965
---
# 示例3：锁频繁抢占

#### 简介

多线程程序，经常会存在锁频繁抢占问题，锁的争抢会导致CPU的资源浪费，可以基于实际的业务减少公共资源的抢占。本示例主要针对这一问题，通过鲲鹏DevKit系统性能分析工具锁与等待分析功能来观测，建议用户分析业务逻辑减少锁的争抢，例如大锁变小锁，减少线程并发数等。


#### 环境准备

1. 请确认服务器上已安装的操作系统是否兼容，GCC版本是否为7.3.0及以上，兼容性请参见DevKit兼容性查询助手(https://www.hikunpeng.com/zh/developer/developtool)。
2. 请确认服务器上是否已安装鲲鹏DevKit系统性能分析工具。
3. 请从GitHub(https://github.com/kunpengcompute/devkitdemo/tree/main/Hyper_tuner/testdemo/lock)下载代码样例，执行以下命令赋予所有用户可读、可写和可执行权限。
  样例代码文件为：pthread_atomic.c、pthread_mutex.c。

  1 chmod 777 pthread_mutex.c pthread_atomic.c


#### 性能分析过程

1. 程序准备。

  a. 编译pthread_mutex.c并赋予执行文件所有用户可读、可写和可执行权限。
    1 gcc -g pthread_mutex.c -o pthread_mutex -lpthread && chmod 777 pthread_mutex

    demo要求GCC版本在7.3以上，若需要关联源码，建议编译时加上-g参数，如：gcc -g pthread_mutex.c -o pthread_mutex -lpthread。 若使用的GCC版本为10.x.x及以上，因该版本默认启用LSE指令集，可能优化效果不明显，建议编译程序时添加参数“-march=armv8-a+nolse -mno-outline-atomics”用以禁用该指令集。 本实践除了锁与等待的分析对象为应用级外，其他模块均为系统级调优，进程和资源调度任务为了分析锁抢占情况，锁与等待任务定位优化锁抢占。

  b. 后台运行程序，nohup命令使得即使退出账户之后会继续运行相应的进程，防止任务中断。
    1 nohup taskset -c 0-1 ./pthread_mutex >>pthread_mutex.out 2>&1 &

    程序运行的标准输出（1）将会保存到pthread_mutex.out文件，错误信息（2）会重定向到pthread_mutex.out文件。

    该程序一般运行时间为20秒左右，若已运行完成，启动采集任务将无法采集到该程序数据，可修改pthread_mutex.c源码中count参数增加对应运行时间或运行该程序后立即启动采集任务。

  c. 优化后程序pthread_atomic.c使用    1.a
一致的编译方式。
2. 采用锁与等待分析，得到锁的调用情况。
  单击系统性能分析后面的，选择“通用分析”，打开新建任务页面，选择“锁与等待分析”，参数配置完成后单击“确认”启动锁与等待分析任务。

  图1 新建锁与等待分析任务

**表1 任务配置参数说明**

| 参数 | 说明 |
| --- | --- |
| 分析类型 | 锁与等待分析 |
| 分析对象 | 应用。 |
| 模式 | Attach to process。 |
| PID | 选择pthread\_mutex应用对应的进程号。 |
| 采样时长（s） | 60秒。 |
| 其他参数 | 默认。 |


3. 查看采集分析结果。
  图2 锁与等待分析结果总览

  图3 锁快照信息

  在“锁实例分析”页签，发现函数“__pthread_mutex_lock”被两个线程调用次数很多；在“锁快照”页签，查看对应的锁的持有等待时间。


#### 锁抢占优化

实际功能代码的执行速度较快，多线程使用锁的方案会将大量的资源开销消耗在锁竞争上，为减少公共资源的抢占，可通过原子变量无锁的编程方式优化代码。

1. 程序准备。

  a. 编译pthread_atomic.c并赋予执行文件所有用户可读、可写和可执行权限。
    1 gcc -g pthread_atomic.c -o pthread_atomic -lpthread && chmod 777 pthread_atomic

    demo要求GCC版本在7.3以上，若需要关联源码，建议编译时加上-g参数，如：gcc -g pthread_atomic.c -o pthread_atomic -lpthread。 若使用的GCC版本为10.x.x及以上，因该版本默认启用LSE指令集，可能优化效果不明显，建议编译程序时添加参数“-march=armv8-a+nolse -mno-outline-atomics”用以禁用该指令集。

  b. 后台运行程序，nohup命令使得即使退出账户之后会继续运行相应的进程，防止任务中断。
    1 nohup taskset -c 0-1 ./pthread_atomic >>pthread_atomic.out 2>&1 &

    程序运行的标准输出（1）将会保存到pthread_atomic.out文件，错误信息（2）会重定向到pthread_atomic.out文件。

    该程序一般运行时间为20秒左右，若已运行完成，启动采集任务将无法采集到该程序数据，可修改pthread_atomic.c源码中count参数增加对应运行时间或运行该程序后立即启动采集任务。

2. 再次新建锁与等待分析任务（pthread_atomic.c应用）。
  单击系统性能分析后面的，选择“通用分析”，打开新建任务页面，选择“锁与等待分析”，参数配置完成后单击“确认”启动锁与等待分析任务。

  图4 再次新建锁与等待分析任务

**表2 任务配置参数说明**

| 参数 | 说明 |
| --- | --- |
| 分析类型 | 锁与等待分析。 |
| 分析对象 | 应用。 |
| 模式 | Attach to process。 |
| PID | 选择pthread\_atomic应用对应的进程号。 |
| 采样时长 | 60秒。 |
| 其他参数 | 默认。 |


  图5 优化后锁与等待任务

  发现锁实例的计数和总时长大幅降低。
