1、多线程中使用fork存在隐患!
参考下图:
左侧------进程包含主线程,线程A,线程B三个线程以及一个全局互斥锁变量
右侧------线程B通过fork创建一个新的进程,新的进程在虚拟地址空间和左侧的进程空间完全一致(拷贝一份),并且只有一个主线程
1.1、考虑问题
问题情形:
第一步、
左侧的线程A/线程B/主线程当中 任意一个线程在线程B fork之前对互斥锁有Lock操作,前面已经强调了,fork产生的新进程是对父进程地址空间的拷贝
第二步、左侧进程空间互斥锁的lock状态通过fork函数,造成右侧进程得到的互斥锁为lock状态
第三步、右侧主线程在不知情的情况下,对互斥锁加锁,意外发生了,右侧线程会阻塞!
代码示例:
// An highlighted block
var foo = 'bar';
1.2、读者问题
乐于思考问题的朋友们可能会发问,这个情况我们可以通过多写两行代码避免吧?
自然可以!
诀窍在于:子进程在开始的时候解锁!
下图有个不可不提的地方,线程B在fork之前应当对mutex加锁。
笔者认为主要原因是需要设置mutex为一个明确的状态:Locked,这样线程B后面的unlock操作不会引起同步问题以及子进程直接unlock操作
代码示例:
// An highlighted block
var foo = 'bar';
2、线程中fork 须慎用!
我们大家都知道,一个程序的执行可能需要很多的系统库;系统库中相当的库函数都是线程安全的…(使用了锁)
- 考虑一下,自己写出来的互斥锁,看的见的代码,我们还可以借用1.2一节的方法避免这个问题
- 但是那么多的系统库函数,也许每一个库函数都有一个锁(这些锁还看不见),比如一个malloc函数,如果从父进程中继承来的malloc互斥锁被加锁,子进程一旦运行malloc就会hang在那里了!!!
3、推荐链接
https://blog.csdn.net/ababab12345/article/details/102897529
https://blog.csdn.net/codinghonor/article/details/43737869
来源:CSDN
作者:Johhny Rade
链接:https://blog.csdn.net/uncle103/article/details/103473714