发现问题

公司项目测试的时候,发现运行一段时间后会出现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杂谈:进程锁核+实时线程导致的读写锁死循环的更多相关文章

  1. 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...

  2. Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...

  3. 看linux连接进程占用的实时流量iftop netatop NetHogs

    因为新工厂的机器上面的业务混合部署非常严重,加上内网外网共用一个网卡(这个更不可思议),导致有时要定位一些进程流量的问题非常困难,所以最近花了点时间在网上搜集了一把  (aptitude search ...

  4. 关于linux的进程中的各个线程cpu占用情况的分析和查看

    我们常常会在新开的服搭建一个游戏的server,有时候要进行压力測试,那么怎样来看呢,一般我们会通过top命令查看各个进程的cpu和内存占用情况,获得到了我们的进程id,然后我们或许会通过pstack ...

  5. 查看linux连接进程占用的实时流量 -nethogs

    1.安装nethogs yum -y install nethogs 2.安装完成后,就可以执行命令 nethogs 3.实时查看进程流量,来个图显示 图中会显示当前的nginx产生的流量有多少都会清 ...

  6. Linux下同进程多进程号实时监控

    一.需求: Linux上对一个进程名称可能会对应的多个进程号的进程进行监控,如果有多个则输出到一个日志文件. 以上问题针对的是一个定时程序还未运行结束,到下一个时刻程序又运行起来了,避免造成重复调用接 ...

  7. Linux内核中锁机制之原子操作、自旋锁

    很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实是由于操作系统中存在多进程对共享资源的并发访问,从而引起了进程间的竞态.这其中包括了我们所熟知的SMP系统,多 ...

  8. 大话Linux内核中锁机制之原子操作、自旋锁

    转至:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其 ...

  9. 大话Linux内核中锁机制之原子操作、自旋锁【转】

    转自:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实 ...

随机推荐

  1. Spring学习(四)--Spring的IOC

    1.BeaDefinition的Resource定位 (1)直接使用BeanDefinitionFactory 定义一个Resource来定位容器使用的BeanDefinition. Resource ...

  2. Python-一切皆对象

    Python 动态.灵活根本是什么? Python中一切皆对象,面向对象更加彻底,函数.类也是对象,属于一等公民 一等公民特性 1. 可以赋值给一个变量 def name(name="北门吹 ...

  3. spring-boot-route(四)全局异常处理

    在开发中,我们经常会使用try/catch块来捕获异常进行处理,如果有些代码中忘记捕获异常或者不可见的一些异常出现,就会响应给前端一些不友好的提示,这时候我们可以使用全局异常处理.这样就不用在代码中写 ...

  4. JDK1.8新特性之(一)--Lambda表达式

    近期由于新冠疫情的原因,不能出去游玩,只能在家呆着.于是闲来无事,开始阅读JDK1.8的源代码.在开始之前也查询了以下JDK1.8的新特性,有针对性的开始了这段旅程. 只看不操作,也是不能心领神会的. ...

  5. 092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 02 static关键字(中)

    092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  6. 008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字

    008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字 关键字 关键字就是一些有特殊意义的词 之前学习的程序中涉及到的关键字 Java中 ...

  7. Java知识系统回顾整理01基础05控制流程08综合练习

    一.练习--黄金分割点 题目: 寻找某两个数相除,其结果 离黄金分割点 0.618最近 分母和分子不能同时为偶数 分母和分子 取值范围在[1,20] (即1到20) 要求效果: public clas ...

  8. Oracle体系结构概述与SQL解析剖析

    Oracle服务器 是一个数据库管理系统,它提供了一种全面.开放.集成的方法来管理信息. Oracle服务器由Oracle数据库和Oracle实例组成. oracle数据库软件和Oracle数据库软件 ...

  9. 非阻塞I/O和阻塞I/O

    1.简介 等待队列实现在事件上的条件等待:希望等待特定事件的进程把自己放进合适的等待队列,并放弃控制权.可用于: - 中断处理 - 进程同步 - 定时 2.等待队列头数据结构 1 typedef st ...

  10. 简单的Linux下的socket通信,小程序,方便以后查看。

    首先是我的一个出错提示的头文件<myerr.h>,自从用了根本停不下来啊!!! #ifndef _MYERR_H_ #define _MYERR_H_ #include <stdio ...