发现问题

公司项目测试的时候,发现运行一段时间后会出现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. Centos-获取远程主机对应端口信息-telnet

    telnet 通过 telnet协议与远程主机通信或者获取远程主机对应端口信息 格式 telnet URL/IP port

  2. Prime Path(POJ - 3126)【BFS+筛素数】

    Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...

  3. 在sqlserver中创建表

    1:在sql语句中,临时表有两类,分别是局部(local)和全局(global)临时表,局部临时表只在其会话(事务)中可见,全局临时表可以被会话(事务)中的任何程序或者 模块访问 2:创建局部临时表 ...

  4. 048 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 10 案例——阶乘的累加和

    048 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 10 案例--阶乘的累加和 本文知识点:通过案例练习嵌套循环应用 案例练习--阶乘的累加和 案例题目 ...

  5. error C2065: “uint8_t”: 未声明的标识符

    转载:https://blog.csdn.net/lys07962000/article/details/12052571 参考: http://blog.csdn.net/chenxin_130/a ...

  6. 基于Intel x86 Android的RAD游戏开发

    zip文件还包含编译的"MonkeyGame-debug".可以在模拟器中运行的二进制文件.在"game.build"文件夹中有一个HTML5 build.在C ...

  7. SSIS 生成文件

    程序说明 此SSIS的目标是生成如下的文本文件 此文件的列由TAB键分割,可以使用notepad++来查看 这样就能够看清TAB键了 文件由%H%表示头部和%D%表示的细节部分 以下为程序开发使用的V ...

  8. 用 Java 实现的八种常用排序算法

    八种排序算法可以按照如图分类 交换排序 所谓交换,就是序列中任意两个元素进行比较,根据比较结果来交换各自在序列中的位置,以此达到排序的目的. 1. 冒泡排序 冒泡排序是一种简单的交换排序算法,以升序排 ...

  9. LVS搭建

    LVS集群搭建 NAT架构图 1.在RS188,RS189操作 #安装httpd服务[root@t1 ~]# yum install -y httpd[root@t1 ~]# echo "I ...

  10. tomcat加载失败

    tomcat启动加载信息如下: Connected to server [2017-10-16 09:02:28,149] Artifact basic-admin:war exploded: Art ...