首页 > 编程语言 > 详细

[APUE] 线程和fork

时间:2014-04-18 07:10:54      阅读:492      评论:0      收藏:0      [点我收藏+]

1 线程中调用fork()产生的问题

线程可以通过调用fork()来创建新的进程,新的进程只有一个线程,它是调用fork()的线程的副本。由于写时拷贝(创建新的进程时,子进程共享父进程的地址空间,只有父进程或者子进程进行写操作时,才会拷贝父进程的东西来创建新的子进程的地址空间)的作用,此时的子进程中的线程共享父进程的调用fork()的线程的地址空间,如果父进程或者子进程对内存做了改动,就会创建父进程的副本,此时,子进程就从父进程那么继承了所有互斥量、读写锁和条件变量的状态。但是,如果父进程在调用fork()之前就获得了某些锁,而子进程获得的状态是锁定的,它就没有办法知道是否该释放哪些锁。换句话说,子进程中的锁是被不存在的线程锁定的。因此,该锁永远不会被释放,

2 解决方案

通常建议,在调用fork()后,子进程立即调用exec()来重置子进程的所有状态。

但是,这并没有从根本上解决问题。应用程序并不知道关于锁的任何问题,他们可能会在fork()和exec()之间调用其它的函数,那么,原来的问题还是来了。

为了解决这个问题,poxis多线程库提供了pthread_atfork()函数。

pthread_atfork()为多线程提供了一种保护子进程的机制,允许程序清理锁的状态。

int pthread_atfork(void (*prepare)(), void (*parent)(), void (*child)());


从它的原型可以看到,它的参数是三个函数:prepare, parent, child。他们分别在三个时期进行调用。

prepare由父进程在fork()创建子进程前调用,负责获取父进程的所有锁。

parent在fork()创建子进程之后,返回子进程前在父进程环境中调用,负责释放prepare获得的所有锁。

child在fork()返回之前,在子进程环境中调用,负责释放prepare获得的所有锁。

[APUE] 线程和fork,布布扣,bubuko.com

[APUE] 线程和fork

原文:http://blog.csdn.net/luofengmacheng/article/details/23954503

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!