这两天有同学使用数据校验工具时发现进程hang住了,也不知道什么原因,我简单看了看进程堆栈,问题虽然很简单,但能导致程序hang住,也一定不是小问题。简单说明下程序组件的结构,程序由两部分构成,dbchk和dbchk_inner,dbchk采用python代码实现,dbchk_inner采用C语言实现。dbchk负责并发控制,dbchk_inner则负责具体的校验任务。用户通过运行dbchk命令即可达到校验的目的。进程关系如下:

$ pstree 18649

dbchk─┬─sh───dbchk_inner───2*[{scandiff}]

└─{dbchk}

回到问题本身,我用测试用例复现了hang住了场景,查看了dbchk和dbchk_inner的堆栈信息,信息如下:

dbchk进程18649堆栈信息:

$ pstack 18649

Thread 2 (Thread 0x7f4343fff700 (LWP 18658)):

#0 0x000000346f80f09d in waitpid () from /lib64/libpthread.so.0

#1 0x000000347190ff8a in ?? () from /usr/lib64/libpython2.6.so.1.0

#2 0x00000034718de706 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0

#3 0x00000034718e0797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0

dbchk_inner进程18660堆栈信息:

pstack 18660

#0 0x000000346f4da3dd in write () from /lib64/libc.so.6

#1 0x000000346f470fd3 in _IO_new_file_write () from /lib64/libc.so.6

#2 0x000000346f470e9a in _IO_new_file_xsputn () from /lib64/libc.so.6

#3 0x000000346f46705d in fwrite () from /lib64/libc.so.6

#4 0x00000000004136f0 in Scanner::run(unsigned int) ()

可以看到父进程dbchk在卡在waitpid()函数,这个容易理解,它应该在等待子进程dbchk_inner结束;再看子进程dbchk_inner,dbchk_inner卡在fwrite()函数,这个就有点奇怪了,为啥写会被阻塞呢?首先想到的是磁盘空间不够了?看了下磁盘空间还有很大的剩余,那还有什么可能导致write卡住,还有一种可能就是缓冲区满了,写不下去。

基于这个思考,回头看看dbchk的代码

pio = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()

可以看到程序里使用了Popen的wait函数,这可以解释父进程为啥会卡住,因为子进程没有执行完;注意Popen的参数,将stdout和stderr输出重定向到了subprocess.PIPE,这个值表示父子进程之间的管道。那么子进程写缓冲区卡住,应该就是因为PIPE的缓冲区满了。为啥会满呢,一是产生的数据太多;另一方面是没有进程去缓冲区去取数据,导致缓冲区只进不出。PIPE缓冲区默认值大小4096个字节,这个可以通过ulimit -a得到,8*512=4096字节,并且这个值不可以修改的,因为值是定义在linux的头文件里面,除非你重新编译linux内核。

$ ulimit -a

core file size (blocks, -c) 0

……

pipe size (512 bytes, -p) 8

好了问题找到了,PIPE缓冲区满是罪归祸首,如何解这个问题?

1.不将stdout和stderr重定向管道,直接输出

2.程序控制输出到管道数据的大小

管道在进程间通信(IPC)使用很广泛,shell命令就使用的很广泛。比如:

ps –aux | grep mysqld

上述命令表示获取mysqld进程相关的信息。这里ps和grep两个命令通信就采用了管道。管道有几个特点:

1.      管道是半双工的,数据只能单向流动,ps命令的输出是grep的输出

2.      只能用于父子进程或兄弟进程通信,这里可以认为ps和grep命令都是shell(bash/pdksh/ash/dash)命令的子进程,两者是兄弟关系。

3.      管道相对于管道两端的进程而言就是一个文件,并且只存在于内存中。

4.      写入端不断往管道写,并且每次写到管道末尾;读取端则不断从管道读,每次从头部读取。

到这里大家可能会有一个疑问,管道两端的进程,写入进程不断的写,读取进程不断的读,那么什么时候结束呢?比如我们刚刚这个命令很快就结束了,它的原理是怎么样的呢?对于管道,这里有两个基本原则:

1.当读一个写端已经关闭的管道时,在所有数据被读取后,read返回0,以指示达到文件结束处。

2.当写一个读端已经关闭的管道时,会产生sigpipe信息。

结合这个例子,当ps写管道结束后,就会自动关闭,此时grep进程read就会返回0,然后自动结束。

参考文档:

《UNIX环境高级编程》

http://blog.chinaunix.net/uid-26833883-id-3227144.html

一次进程hang住问题分析。。。的更多相关文章

  1. 一次数据库hang住的分析过程

    现象: 普通用户和sysdba都无法登陆,业务中断 分析过程: 1.先做hanganalyze和systemstate dump $sqlplus -prelim "/as sysdba&q ...

  2. truncate表hang住(等待时间较长),出现enq:RO fast object reuse等待事件

    有一个应用truncate表等待了一晚上,一个定时任务,跑了几年了,今天早上来发现昨晚没有执行完成,hang住了,查询发现等待事件 fast object reuse. 10.2.0.4的库 Bug ...

  3. debug实战:进程Hang+High CPU

    最近几周都在解决程序不稳定的问题,具体表现为程序(多进程)时不时的Hang住,同时伴随某个进程的High CPU.跟踪下来,基本都是各种死锁引起的.这里选取一个典型的场景进行分析. 1.抓dump分析 ...

  4. 如何诊断oracle数据库运行缓慢或hang住的问题

    为了诊断oracle运行缓慢的问题首先要决定收集哪些论断信息,可以采取下面的诊断方法:1.数据库运行缓慢这个问题是常见还是在特定时间出现如果数据库运行缓慢是一个常见的问题那么可以在问题出现的时候收集这 ...

  5. ShellExecuteEX打开iqy文件导致excel hang的原因分析

    1. 问题 当在console中调用API ShellExecuteEx打开"test.iqy"文件时,发现excel会hang住,console退出后excel才会响应,但直接双 ...

  6. 11.2.0.3 RAC(VCS)节点crash以及hang的问题分析

    昨天某个客户的一套双节RAC当中一个节点crash,同一时候最后导致另外一个节点也hang住,仅仅能shutdown abort. 且出现shutdown abort实例之后,还有部分进程无法通过ki ...

  7. 如何定位 golang 进程 hang 死的 bug

    之前在 golang 群里有人问过为什么程序会莫名其妙的 hang 死然后不再响应任何请求.单核 cpu 打满. 这个特征和我们公司的某个系统曾经遇到的情况很相似,内部经过了很长时间的定位分析总结,期 ...

  8. Oracle数据库shutdown immediate被hang住的几个原因

    实验操作环境:         操作系统:Red Hat Enterprise Linux ES release 4 (Nahant Update 6)                         ...

  9. 一则因为numa引发的mysqldump hang住

    新买的dell r430服务器,双CPU,64G内存,单CPU32g,swap 3G 出现故障现像:mysqldump时会hang住,innodb_buffer_pool_size        = ...

随机推荐

  1. Redis使用总结

    1.Redis安装 redis的安装非常的简单,而且Redis并不依赖其他环境和标准库,很容易上手,这可能也是它流行的一个原因.这里为了测试方便,用的都是windows 环境下测试.下载Windows ...

  2. .Net 高效开发之不可错过的实用工具(转)

    .Net 高效开发之不可错过的实用工具(转) 本文摘自: http://www.cnblogs.com/powertoolsteam/p/5240908.html#3372237 Visual Stu ...

  3. 背水一战 Windows 10 (10) - 资源: StaticResource, ThemeResource

    [源码下载] 背水一战 Windows 10 (10) - 资源: StaticResource, ThemeResource 作者:webabcd 介绍背水一战 Windows 10 之 资源 St ...

  4. php中的字符串常用函数(五) explode 妙用

    // 示例 2 $data = "foo:*:1023:1000::/home/foo:/bin/sh" ; list( $user , $pass , $uid , $gid , ...

  5. HDU 1131 Count the Trees 大数计算

    题目是说给出一个数字,然后以1到这个数为序号当做二叉树的结点,问总共有几种组成二叉树的方式.这个题就是用卡特兰数算出个数,然后因为有编号,不同的编号对应不同的方式,所以结果是卡特兰数乘这个数的阶乘种方 ...

  6. Cookie——Javascript

    基本的cookie操作有三种:读取.写入.删除. var CookieUtil = { //根据cookie的name获取相应的value.它会在document.cookie字符串中查找cookie ...

  7. percona server 5.7.16正式发布

    继2016年10月12日mysql 5.7.16发布后,percona server 5.7.16终于于11月29日发布了,这是最新版本的5.7系列,可从https://www.percona.com ...

  8. NProgress.js template

    NProgress.js:加载进度条:http://ricostacruz.com/nprogress/ 基础的这几个方法 这个网站上都有 我在一个地方看到这个代码 NProgress.configu ...

  9. 使用 jQuery & CSS3 实现优雅的手风琴效果

    手风琴效果常用于切换显示一组内容,这种方式既可以节省网页空间又可以有动画效果.今天,我们将创造一个优雅的手风琴内容效果.这个想法是有悬停时滑出一些垂直手风琴标签.我们将添加一些 CSS3 属性来提升外 ...

  10. 【特别推荐】几款极好的 JavaScript 下拉列表插件

    表单元素让人爱恨交加.作为网页最重要的组成部分,表单几乎无处不在,从简单的邮件订阅.登陆注册到复杂的需要多页填写的信息提交功能,表单都让开发者花费了大量的时间和精力去处理,以期实现好用又漂亮的表单功能 ...