出自一个unix锁的问题解答

系统 其他OS
当主线程退出的时候,操作系统会直接终止该进程里面的其它线程,不会留任何机会让那个线程做退出处理。而那个线程可能恰恰刚刚获的了unix锁,而还没来得及解锁,就被扼杀了。

在unix上做C的开发已经快2年了,一直在我们部门的一个主要产品项目组工作,该产品在大部分客户那里一直稳定的运行,没有任何问题,而在少数几个客户那里,时不时的出现整个系统的吊死,而且该问题没有任何规律可寻,除了系统吊死时候,我们对整个系统用pstack进行所有进程堆栈的跟踪记录外,我们没有任何其它线索,没有系统崩溃时候产生的CORE,我们开始面对来自客户强大的压力。

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

我们知道,当主线程退出的时候,操作系统会直接终止该进程里面的其它线程,不会留任何机会让那个线程做退出处理。而那个线程可能恰恰刚刚获的了unix锁,而还没来得及解锁,就被扼杀了,于是就造成了其它进程或线程再加这个unix锁的时候,就会被阻塞,系统死锁问题也就浮现了出来。

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

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

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

  1. pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);  
  2. pthread_mutexattr_setrobust_np(&mattr,PTHREAD_MUTEX_ROBUST_NP); 

通过设置锁的上面两个属性,我们就改变了默认的行为,当一个unix锁的owner死掉后,其它线程再去加这个锁的时候,不会被阻塞,而是通过返回值EOWNERDEAD来报告错误,那么你可以根据这个错误来进行处理:首先是应该调用pthread_mutex_consistent_np函数来恢复该锁的一致性,然后调用解锁pthread_mutex_unlock,接下来在调用加锁,这样该锁的行为就恢复正常了。

如果上面这个函数在恢复unix锁的一致性时候没有成功,那么你只需要调用解锁函数就OK了,然后直接返回,而不要去调用加锁函数,那么接下来的线程在调用加锁函数的时候,会得到返回值ENOTRECOVERABLE,那么需要你做的就是调用pthread_mutex_destroy来destroy掉该锁,然后重新用锁的属性和unix锁的初始化函数来重新初始化该锁。

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

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

【编辑推荐】

  1. Unix操作系统中Minix讲解
  2. 简单介绍Unix系统中打印知识
  3. Unix操作系统打印问题解决
  4. 当Unix系统遇到病毒时
  5. Unix操作系统知识讲解
责任编辑:小霞
相关推荐

2011-05-10 14:14:10

OSPF路由

2011-05-10 14:32:19

OSPF路由

2011-10-20 09:57:58

AS400 FTPFTP

2010-10-09 17:19:50

mysql存储过程

2011-05-10 15:30:22

SEO

2009-10-13 14:56:00

CCNA培训

2011-07-13 17:57:15

SQLite

2009-12-25 10:59:08

WPF Timer

2010-07-26 13:05:44

Perl子程序参数

2010-09-13 14:43:47

无线技术常见问题

2011-08-09 15:10:00

SQLite

2023-10-10 08:01:13

2011-04-14 10:46:23

2021-02-26 22:54:06

云计算公有云私有云

2009-10-27 11:10:56

linux问题解答

2020-08-20 10:41:28

云计算云安全数据

2009-12-03 18:09:51

Visual Stud

2011-07-21 11:19:51

JAVA

2010-05-12 17:04:20

BlackBerry开

2020-10-16 08:24:40

物联网网关物联网IOT
点赞
收藏

51CTO技术栈公众号