Linux杂谈:进程锁核+实时线程导致的读写锁死循环
发现问题
公司项目测试的时候,发现运行一段时间后会出现cpu百分之百的情况。
想着可能是哪里出现了死循环,于是打算用gdb跟一下,结果gdb居然无法attach到进程。。。。。。
定位问题
查了查去,原来有一个优先级为RT的实时线程出现了死循环,并且由于配置了CPU的亲和属性,使得进程只运行在第一个核上,此时gdb就无法attach了
使用taskset现场修改进程的cpu亲和属性后,发现这个占cpu百分百的实时线程并没有出现一般的死循环,而是每次都在pthread_rwlock_wrlock这个函数中,
而更诡异的是,只要修改了cpu亲和属性,就没有“死循环了”。。。。。。
实验
于是写了一段实验代码
1 #define _GNU_SOURCE
2 #include "stdio.h"
3 #include "stdlib.h"
4 #include "unistd.h"
5 #include "pthread.h"
6 #include <sched.h>
7
8 pthread_rwlock_t rwlock;
9
10 void* task1(void *arg)
11 {
12 pthread_setname_np(pthread_self(), "task1");
13
14 while(1)
15 {
16 printf("\r\n task1 lock \r\n");
17 pthread_rwlock_wrlock(&rwlock);
18
19 printf("\r\n task1 unlock \r\n");
20 pthread_rwlock_unlock(&rwlock);
21
22 usleep(10);
23 }
24 }
25
26 void* task2(void *arg)
27 {
28 struct sched_param sparam;
29
30 pthread_setname_np(pthread_self(), "task2");
31
32 /* 设置为最高优先级的实时任务 */
33 sparam.sched_priority = sched_get_priority_max(SCHED_RR);
34 pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
35
36 while(1)
37 {
38 printf("\r\n task2 lock \r\n");
39 pthread_rwlock_wrlock(&rwlock);
40
41 printf("\r\n task2 unlock \r\n");
42 pthread_rwlock_unlock(&rwlock);
43
44 usleep(10);
45 }
46 }
47
48 int main(int argc, char *argv[])
49 {
50 pthread_t t1, t2, t3;
51 cpu_set_t cpuset;
52
53 /* 设置cpu亲和属性,将进程绑定在第一个核上 */
54 CPU_ZERO(&cpuset);
55 CPU_SET(0, &cpuset);
56 sched_setaffinity(0, sizeof(cpuset), &cpuset);
57
58 pthread_rwlock_init(&rwlock, NULL);
59
60 pthread_create(&t2, NULL, task1, NULL);
61 sleep(3);
62 pthread_create(&t3, NULL, task2, NULL);
63
64 while (1)
65 sleep(10);
66
67 return 0;
68 }
运行结果,如下图
真的出现了CPU百分百的情况!!!
分析原因
1. 读写锁的“拿锁”和“放锁”操作并不是一个完整的原子操作,而是有可能操作到一半被调度出去;
2. 此次实验结果显示,task1(非实时)在做unlock操作时,已经修改了一部分读写锁的属性,此时task2(实时)lock时,发现不需要再阻塞了,只需要自旋等待(死循环)task1将unlock操作做完;
然而由于task1是实时任务,整个进程又只绑定到了第一个核上,task1无法得到调度,造成了task2的死循环。
Linux杂谈:进程锁核+实时线程导致的读写锁死循环的更多相关文章
- 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁
大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...
- Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁
在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...
- 看linux连接进程占用的实时流量iftop netatop NetHogs
因为新工厂的机器上面的业务混合部署非常严重,加上内网外网共用一个网卡(这个更不可思议),导致有时要定位一些进程流量的问题非常困难,所以最近花了点时间在网上搜集了一把 (aptitude search ...
- 关于linux的进程中的各个线程cpu占用情况的分析和查看
我们常常会在新开的服搭建一个游戏的server,有时候要进行压力測试,那么怎样来看呢,一般我们会通过top命令查看各个进程的cpu和内存占用情况,获得到了我们的进程id,然后我们或许会通过pstack ...
- 查看linux连接进程占用的实时流量 -nethogs
1.安装nethogs yum -y install nethogs 2.安装完成后,就可以执行命令 nethogs 3.实时查看进程流量,来个图显示 图中会显示当前的nginx产生的流量有多少都会清 ...
- Linux下同进程多进程号实时监控
一.需求: Linux上对一个进程名称可能会对应的多个进程号的进程进行监控,如果有多个则输出到一个日志文件. 以上问题针对的是一个定时程序还未运行结束,到下一个时刻程序又运行起来了,避免造成重复调用接 ...
- Linux内核中锁机制之原子操作、自旋锁
很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实是由于操作系统中存在多进程对共享资源的并发访问,从而引起了进程间的竞态.这其中包括了我们所熟知的SMP系统,多 ...
- 大话Linux内核中锁机制之原子操作、自旋锁
转至:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其 ...
- 大话Linux内核中锁机制之原子操作、自旋锁【转】
转自:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实 ...
随机推荐
- How to read h5 file by Matlab
In matlab, one can use the following command to read h5 file data = h5read(filename,ds) data = h5rea ...
- java 线程池、多线程实战(生产者消费者模型,1 vs 10) 附案例源码
导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...
- VS2013 C++ 生成与调用DLL(动态链接库) 需要验证
转载:https://blog.csdn.net/s978697043/article/details/82429802 一.创建动态链接库(生成.dll .lib 两个文件) 文件→新建→项目 选择 ...
- Apache账户密码加密方式介绍
一.apache密码存储格式 apache的用户密码一般会生成保存在.htpasswd文件中,保存路径由用户创建时确定,根据使用加密算法有五种保存格式: [注]:如果用户指定了保存密码的文件名,视用户 ...
- JavaScript利用函数反转数组
要求: 给定一数组,将其元素倒序排列并输出. 代码实现: // 利用函数翻转任意数组 reverse 翻转 function reverse(arr) { var newArr = []; for ( ...
- 二进制部署Redis-5.07
Redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理. 它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类 ...
- angular http 跨域访问
1.在跟目录中创建配置文件:proxy.config.json ,文件内容如下: { "/api": { "target": "http://192. ...
- TMS, XYZ & WMTS的不同
WMS是OGC定义的协议,用于请求任意区域的渲染地图图像.客户可以根据需要以平铺模式对其进行请求. WMS-C是OSGeo创建的WMS扩展,它向功能文档中添加了元数据,以使客户端知道在哪里发出请求,从 ...
- [Docker]linux异常关机,docker镜像丢失
在运行中的docker容器遇到意外情况,可能会自动终止运行,例如磁盘空间不足. 解决办法: 找到/var/lib/docker/containers文件夹下的所有容器ID 执行命令,查看容器信息 ,找 ...
- Java 10 种常用第三方服务
严格意义上说,所有软件的第三方服务都可以自己开发,不过从零到一是需要时间和金钱成本的.就像我们研发芯片,投入了巨大的成本,但仍然没有取得理想的成绩,有些事情并不是一朝一夕,投机取巧就能完成的. Jav ...