fork与多线程
来源:互联网 发布:网络情感障碍空虚 编辑:程序博客网 时间:2024/04/29 10:33
如果一个多线程程序调用了fork,那么新创建的子进程只拥有一个执行线程(调用fork的那个线程的完整复制),并且子进程自动继承父进程的互斥锁(条件变量)的状态,即父进程中被加锁的互斥量在子进程中也是被锁住的。于是子进程不知道继承而来的互斥量的具体状态,若互斥量在fork前已经被加锁,子进程若再对互斥量加锁则一定死锁。当然若fork后的子进程立即调用exec()执行其它程序隔断了父子关系则不会出现上述情形。
pthread_atfork可以清除锁状态,以确保fork调用后父子进程都拥有一个清除的锁状态。 int pthread_atfork(void(*prepare)(void),void(*parent)(void),void(*child)(void));建立三个fork句柄来清理互斥量的状态,prepare句柄在fork系统调用前被执行用来锁住所有父进程中的互斥锁,parent在fork创建子进程后但是在fork返回前在父进程中执行释放所有在prepare被锁住的互斥量,child句柄是在fork返回之前,在子进程中执行,释放所有在prepare句柄中被锁住的互斥锁。多线程调用fork时可以用,若是单线程fork或者exec则没有必要用这个。
还有就是父进程创建的对象子进程进程了最后对象会被析构两次,则构造和析构就不是成对出现了。如果对象是采用RAII手法封装的某种资源,如定时器子进程不会继承,而RAII对象在子进程的析构可能会试图释放一个不存在的资源。所以多线程中尽量不要fork调用。
#include <pthread.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <wait.h>pthread_mutex_t mutex;void* another( void* arg )//线程函数{ printf( "in child thread, lock the mutex\n" ); pthread_mutex_lock( &mutex ); sleep( 5 );//###1### pthread_mutex_unlock( &mutex );}void prepare()//pthread_atfork的句柄{ pthread_mutex_lock( &mutex );}void infork(){ pthread_mutex_unlock( &mutex );}int main(){ pthread_mutex_init( &mutex, NULL ); pthread_t id; pthread_create( &id, NULL, another, NULL ); //pthread_atfork( prepare, infork, infork );//在fork前调用pthread_atfork使父子进程都拥有一个清楚的锁状态,则不会出现死锁###2### sleep( 1 );//让线程锁住互斥量 int pid = fork(); if( pid < 0 ) { pthread_join( id, NULL ); pthread_mutex_destroy( &mutex ); return 1; } else if( pid == 0 ) { printf( "I am in the child, want to get the lock\n" ); pthread_mutex_lock( &mutex );//子进程继承了父进程的互斥锁状态,该互斥量是锁住的###1###,则子进程加锁出现死锁 printf( "I can not run to here, oop...\n" ); pthread_mutex_unlock( &mutex ); exit( 0 ); } else { pthread_mutex_unlock( &mutex ); wait( NULL ); } pthread_join( id, NULL ); pthread_mutex_destroy( &mutex ); return 0;}不调用pthread_atfork###2###的输出:
in child thread, lock the mutex
I anm in the child, want to get the lock
^C //死锁,只有中断了
调用pthread_atfork###2###不注释的输出:
in child thread, lock the mutex
I am in the child, want to get the lock
I can not run to here, oop... //子进程没有出现死锁
- 多线程程序与fork()
- 多线程程序与fork() .
- 多线程与fork
- 多线程程序与fork()
- 多线程与fork
- 多线程与fork
- fork与多线程
- 多线程与fork
- 102-多线程与 fork
- 多线程程序与fork()分析
- fork()函数与Linux中的多线程编程
- fork() 函数与 Linux 中的多线程编程
- fork()函数与Linux中的多线程编程
- 多线程 fork
- fork与fork函数
- 论fork()函数与Linux中的多线程编程
- 论fork()函数与Linux中的多线程编程
- 论fork()函数与Linux中的多线程编程
- 就象小姐妹一样亲热
- Jakarta-ORO正则表达式库
- 如果没有了水人们个个脸色苍白
- linux系统开发基础1
- 尹艳丽该文感情真挚
- fork与多线程
- 妈妈买了水果去感谢吴吴老师
- 水对于我们是多么的重要
- 各种资源的人均占有量还会继续下降
- linux系统开发基础2
- 哄起我来爸爸在前线战斗的这段漫长岁月里
- 生出一番观沧海的磅礴气势
- 今天的老鹰第一次进攻的吃饭
- ASP.NET中常用的26个优化性能方法