unix上防止程序死锁的一些手段

原创 2004年05月12日 18:29:00

在unix上做C的开发已经快2年了,一直在我们部门的一个主要产品项目组工作,该产品在市场上经受了一年半的考验,可以说已经是很成熟的产品了,该产品在大部分客户那里一直稳定的运行,没有任何问题,而在少数几个客户那里,时不时的出现整个系统的吊死,而且该问题没有任何规律可寻,除了系统吊死时候,我们对整个系统用pstack进行所有进程堆栈的跟踪记录外,我们没有任何其它线索,没有系统崩溃时候产生的CORE,我们开始面对来自客户强大的压力。。。。我们几乎喘不过起来,我们要给客户提交故障报告,而这些故障报告的问题都是这一个问题,这个问题开始成为悬在我们头上的一把利剑。

我开始被指派来解决这个问题。其实我们很早的就从进程的堆栈跟踪里知道这个问题是死锁问题,但是,它是怎么发生的那,我们几乎排查了整个系统的代码,但是一无所获。。。

在今年大年初一的时候,我们的系统又一次出现了该问题,当接到我们维护工程师的电话的时候,我的心情非常的沉重,我没有做到我作为一个程序员应有的职责,还是象往常一样,除了进程堆栈跟踪外,我没有任何其它线索,我还是照例接收邮件,查看我们维护工程师发回来的堆栈跟踪记录,可能是过年放假在家里休息了一段时间的缘故,脑袋好像特别清醒,面对堆栈跟踪记录,结合源码,我迅速的意识到造成死锁的原因是经典的竞态条件问题,是一个进程准备退出的时候,它会唤醒它里面的一个线程,该线程首先会获得一个锁,进行后续出来,然后解锁退出,但是由于该进程的主线程没有采用任何方式来等待该线程的退出,而是直接通过return的方式进行了退出,我们知道,当主线程退出的时候,操作系统会直接终止该进程里面的其它线程,不会留任何机会让那个线程做退出处理。而那个线程可能恰恰刚刚获的了锁,而还没来得及解锁,就被扼杀了,于是就造成了其它进程或线程再加这个锁的时候,就会被阻塞,系统死锁问题也就浮现了出来。

当然,我知道了是竞态条件问题造成了死锁,就会通过pthread_join来同步等待那个线程退出,来消除这个竞态条件,也就消除了死锁,问题其实也就解决了。但是,我们有没有办法来消除由于一个锁的owner没有释放该锁,就死掉了,其它线程再加这个锁的时候而造成的死锁问题那?

关于上面这个问题,我曾经在chinaunix请教过很多人,有的人想通过一个网络锁(就是加锁、解锁都要访问网络上的一台机器)来解决,但是这些方法都不成熟,也很复杂,也好像有高手对这个问题不屑。我通过搜集很多资料发现,原来解决这个问题非常的简单,简单的不能在简单了。

在很多系统上,当一个锁的owner没有释放该锁,就退出了,那么默认的方式就是其它线程再去加这个锁的时候,就会阻塞,造成死锁。而通过不同的属性初始化这个锁,我们能够改变这种默认的方式:

pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
pthread_mutexattr_setrobust_np(&mattr,PTHREAD_MUTEX_ROBUST_NP);

通过设置锁的上面两个属性,我们就改变了默认的行为,当一个锁的owner死掉后,其它线程再去加这个锁的时候,不会被阻塞,而是通过返回值EOWNERDEAD来报告错误,那么你可以根据这个错误来进行处理:首先是应该调用pthread_mutex_consistent_np函数来恢复该锁的一致性,然后调用解锁pthread_mutex_unlock,接下来在调用加锁,这样该锁的行为就恢复正常了。如果上面这个函数在恢复锁的一致性时候没有成功,那么你只需要调用解锁函数就OK了,然后直接返回,而不要去调用加锁函数,那么接下来的线程在调用加锁函数的时候,会得到返回值ENOTRECOVERABLE,那么需要你做的就是调用pthread_mutex_destroy来destroy掉该锁,然后重新用锁的属性和锁的初始化函数来重新初始化该锁。

上面的这些解决死锁方式比较适合在系统中只有一个锁的情况,如果系统的死锁是由于多把锁的资源互相等待而造成的,那么这种解决方式无能为力。。。

注:上面有一些函数后面有np后缀的,表示not portable,就是不可移值的意思,这些函数是一些系统自己实现的,而不是POSIX标准。

UNIX环境高级编程——死锁

死锁  操作系统中有若干进程并发执行,它们不断申请、使用、释放系统资源,虽然系统的进程协调、通信机制会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能继续运行,否则就阻塞的情况。此时,若...
  • ctthunagchneg
  • ctthunagchneg
  • 2013年07月17日 11:53
  • 1445

多线程死锁的产生以及如何避免死锁

一、死锁的定义 多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进...
  • ls5718
  • ls5718
  • 2016年07月13日 11:07
  • 19140

死锁及其解决方案(避免、预防、检测)

死锁的产生的条件
  • yyf_it
  • yyf_it
  • 2016年09月02日 11:00
  • 1478

9.死锁的概念、导致死锁的原因,导致死锁的四个必要条件,预防死锁的方法、避免死锁的方法

可以把死锁定义为一组相互竞争系统资源或进行通信的进程间的“永久”阻塞。当一组进程中的每个进程都在等待某个事件(典型的情况是等待所请求的资源释放),而只有在这组进程中的其他被阻塞的进程才可以触发该事件,...
  • xie294777315
  • xie294777315
  • 2014年08月07日 09:54
  • 5040

UNIX环境高级编程——死锁

死锁  操作系统中有若干进程并发执行,它们不断申请、使用、释放系统资源,虽然系统的进程协调、通信机制会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能继续运行,否则就阻塞的情况。此时,若...
  • ctthunagchneg
  • ctthunagchneg
  • 2013年07月17日 11:53
  • 1445

《unix systems for modern architectures》笔记---主从处理器设计和死锁

一.主从处理器设计和短期互斥        短期互斥依赖于内核中绝不会有一个以上的进程同时执行,在MP上实现这一点最简单的技术是要求所有的内核活动都在一个物理处理器上执行,这个处理器为主处理器(ma...
  • Am_111
  • Am_111
  • 2012年09月15日 12:50
  • 1040

UNIX环境高级编程——线程同步之互斥量 && 死锁

1、线程同步之互斥量 互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程。当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行...
  • armlinuxww
  • armlinuxww
  • 2013年07月29日 09:25
  • 693

Web开发中防止程序出现漏洞的一些有效手段

如今的Web应用程序可能会包含危险的安全缺陷。这些应用程序的全球化部署使其很容易遭受攻击,这些攻击会发现并恶意探测各种安全漏洞。    Web环境中两个主要的风险在于:注入——也就是SQL注入,它...
  • wang_quan_li
  • wang_quan_li
  • 2014年11月21日 19:19
  • 968

查看 oracle 死锁程序

  • 2012年03月20日 13:18
  • 565B
  • 下载

如何解决多线程程序中的死锁问题(转)

如何解决多线程程序中的死锁问题     经常在技术论坛上看到有人虎目含泪地向人哭诉被多线程程序中的死锁问题搞得欲死欲仙,最后扔下狠话:再不用多线程了,要用多进程。     的确,死锁问题是一个...
  • zmjingying
  • zmjingying
  • 2011年09月18日 09:47
  • 7955
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:unix上防止程序死锁的一些手段
举报原因:
原因补充:

(最多只允许输入30个字)