免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: crazyhadoop

[Linux] Linux系统开发那点事儿 分享经验得牛人力作!(获奖名单已公布-2014-5-28) [复制链接]

论坛徽章:
0
发表于 2014-04-10 09:27 |显示全部楼层
曾经遇到这么一个问题:
1.在C程序中要用一个C++的库(ICE),通过动态库调用
2.为了能在进程挂了后打印部分函数调用栈信息,捕获除了SIGKILL外的进程退出信号
3.捕获信号后,打印函数栈到一个文件中,调用exit退出

一两个月偶尔出现进程死锁的现象,通过调用strace -p发现进程确实卡在了futex上,但是进程里面找不出死锁代码。
最后通过gcc --pid发现进程先捕获到了退出信号,接着死锁了。
死锁的原因是exit内核进行了资源回收,调用了C++库里面的析构函数,析构函数中获取锁导致死锁。
最后找到问题代码,最后防止出现类似情况使用_exit进行暴力退出。

论坛徽章:
0
发表于 2014-04-10 09:31 |显示全部楼层
回复 11# letmetryok
写错了一个地方,exit的回收操作是C库干的


   

论坛徽章:
2
2016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之广夏
日期:2016-12-07 08:32:11
发表于 2014-04-10 09:57 |显示全部楼层
系统编程初学者,
这几天上操作系统原理上的比较晕,今晚继续看Linux编程顺便看懂了好几个问题。
    随便写几句。
    首先进程和程序的区别,特南鲍姆那本操作系统书上有个很形象的例子,程序相当于食谱做菜步骤,而进程相当于做饭的过程。也就是说进程是一个过程,是用来执行程序代码的。这就有一个问题,如果一个进程在执行一段代码,我想办法把代码给换了会怎么样,于是就有了exec函数,这个函数可以把一个进程所执行的程序代码换掉,执行这个函数后进程还是那个进程,PID什么的没变,但代码不再是以前的代码了,将继续执行新的代码。
与此相关的fork函数,会创建另一个新进程并把当前进程相关的环境变量、堆栈等复制一份给那个新进程(我们将之称为子进程),由于这俩进程共享一份代码,却有不同的内存地址空间(包括环境变量、堆栈等数据),这样的话,每一个进程的堆栈是一样的,当前两个进程都在fork函数中等待返回,于是会返回两次,虽然返回两次但他们执行同一份代码,父进程按照堆栈的指示返回fork值(子进程ID),子进程同样要返回fork值(0),俩进程在各自的进程内返回了自己专属的fork返回值。于是在接下来的共享代码中就可以用switch-case语句根据两次返回值的不同选择不同的代码执行。父进程和子进程里fork返回值分别为PID和0,执行这同一段代码到了switch-case处便会依据返回值选择不同的分支执行。说的略罗嗦。
    如果子进程先挂了,那么他的进程表项不会立即释放,因为之后他的父进程可能会提取一些退出信息,那么这子进程已经挂了,但没释放,就叫做僵尸进程。等到父进程挂了之后子进程的进程表项也就释放了,如果子进程成僵尸了,父进程却异常终止,那么子进程托孤给init进程,由他来释放。
    如果父进程先挂了,那么子进程执行完任务并挂了之后,进程表项就立刻被释放了。

论坛徽章:
1
2016猴年福章徽章
日期:2016-02-18 15:30:34
发表于 2014-04-10 16:16 |显示全部楼层
回复 3# 阿注哥


    看到thrd_cleanup()清理函数没有执行,所以阻塞应该发生在清理函数调用之前。查看pthread_cond_wait()函数的源码发现如下代码:
  1. /* Before we block we enable cancellation.  Therefore we have to
  2.      install a cancellation handler.  */
  3.   __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
复制代码
也就是在自定义清理函数执行之前,nptl先执行__condvar_cleanup()函数,查看__condvar_cleanup()函数源码有如下实现:
  1. /* Get the mutex before returning unless asynchronous cancellation
  2.      is in effect.  */
  3.   __pthread_mutex_cond_lock (cbuffer->mutex);
复制代码
这里应该是造成死锁的地方。不知与您说的是否一致?

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
发表于 2014-04-10 16:58 |显示全部楼层
好活动。支持。

论坛徽章:
0
发表于 2014-04-10 18:31 |显示全部楼层
如何更好的组织代码文件、什么东西单独编译成动态库或静态库,到现在还没这么弄明白

论坛徽章:
0
发表于 2014-04-10 18:41 |显示全部楼层
回复 14# butterfly_c


    兄台高见!哈哈,我找到的也是这里。

论坛徽章:
0
发表于 2014-04-11 09:50 |显示全部楼层
      我从事服务器开发的,我遇到一个诡异问题是,自己实现的cache大小越大,它的性能就越差,经过排查,cache的查找和淘汰的时间都是在合理的范围。最后用perf 工具发现了内核函数find_vma其高无比,cache大小变大(几十G),就会导致find_vma占了很多cpu。
      在我们项目中,为了避开glibc自身分配和回收内存的自身的缺陷,我们大于64k的内存全用mmap分配,mmap分配一般不会导致线性区的变多,因为内核会把相邻的线性区尽可能合并,所以find_vma这个函数按理是不会占很多cpu。我们后来用pmap查看server,发现他的线性区确实异常的多。
      为什么出现这种情况,后来分析得出的结论是:因为cache(几十G)中有申请内存,也有释放内存,虽然我们使用了内存池,但内存池的空闲内存达到一定时,也会放回glibc,所以这种情况,很有可能导致线性空间中的线性区不连续了,这样内核也就不能合并它,所以造成了find_vma异常占cpu

论坛徽章:
1
寅虎
日期:2014-06-05 13:38:02
发表于 2014-04-11 16:11 |显示全部楼层
支持活动   大学那会学了下Linux编程   在工作中用不到   目前已经印象模糊了

论坛徽章:
0
发表于 2014-04-11 17:06 |显示全部楼层
linux感觉好难 反正还没入门呢 才从开始接触
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP