多线程程序的fork
操作
问题一:多线程中某个线程调用 fork()
,子进程会有和父进程相同数量的线程吗?
main添加fork()之后
运行结果
879为同一个进程打印出来的,881属于复制出的子进程进行打印的结果
fork()添加到子线程中
运行结果
此次,进程复制,但是执行路径为fork
所在的线程中。
main
和fun
属于同一个进程。
结论:启用fork()
之后,整个进程被复制,但是只启动fork
所在的那条执行路径。
问题二:父进程加锁之后,fork()后的子进程加的锁和父进程是不是同一个锁?
答:不是
父子进程使用的锁不同,当父进程中的子线程已经处于加锁之后的解锁状态,但是子进程中的锁依旧是加锁。
简单解释:A和B有同样的一本书,这本书是一样的,但是是两本,并不是同一本。
场景示例:父进程=主线程+子线程(加锁、解锁),fork()后的子进程包含加锁、解锁
子线程
主线程
总结:
子进程中会将父进程中锁的状态进行复制,如果此时父进程中锁的状态是加锁,则复制过来的子进程也是处于加锁状态,出现阻塞、死锁现象;反之,如果是解锁状态,子进程中也会是解锁状态的锁。
提问:那能不能在子进程中最开始直接进行解锁操作?
答:不能,子进程复制过来的锁的状态取决于复制的时刻父进程中锁的状态,因此是否为加锁解锁不一定。
总之,子进程中锁的状态不清晰且不能随意进行解锁操作,因为加锁是某些资源需要保护才加锁。
解决方案:
等待父进程中的锁处于解锁的状态之后,再进行复制子进程。
代码修改:
总结:
推迟fork的复制,在fork之前加锁(如果加不上,证明锁正在被使用),保证每次fork之后锁的状态都处于加锁的状态,之后分别在父子进程中进行解锁。