多线程环境使用fork调用

隐身守侯 提交于 2019-12-14 12:15:54

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!