android bionic recursive锁多线程 fock,子进程卡死bug

在 POSIX 标准中,fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略,所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。所有父进程中别的线程,到了子进程中都是突然蒸发掉的。

在bionic pthread_mutex_lock 和pthread_mutex_unlock时,如果用RECURSIVE锁,去lock内部的另一个锁,_recursive_lock,来保证RECURSIVE锁内部逻辑。代码见:android4.0.4/bionic/libc/bionic/pthread.c

fork的逻辑,先执行__bionic_atfork_run_prepare获得一个handler_mutex的RECURSIVE锁,然后再__fork()之后,子进程和父进程分别执行__bionic_atfork_run_parent和__bionic_atfork_run_child来释放这个锁。

代码见:

android4.0.4/bionic/libc/bionic/pthreadatfork.candroid4.0.4/bionic/libc/bionic/fork.c

这样假设一种情况:

父进程有两个线程A和B,线程A去执行fork,先执行__bionic_atfork_run_prepare,获取handler_mutex,然后执行__fork()来产生一个子进程,就在fork的一瞬间

,B线程正好用另一个RECURSIVE锁,进入pthread_mutex_lock或pthread_mutex_unlock,获取_recursive_lock,还没释放,A线程__fork()来产生一个子进程,复制了父进程的所有对象(包括_recursive_lock的状态),而丢掉了B线程。这样_recursive_lock在子进程里永远没人释放。然后子进程试图去执行__bionic_atfork_run_child,执行pthread_mutex_unlock(&handler_mutex),再回获取_recursive_lock时,卡死。

 

这个bug是POSIX标准里,多线程fork bug的一种体现,详细信息可以参照:http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值