线程与exec、fork、exit

线程与exec

只要有任一线程调用了exec()系列函数之一时,调用程序将被完全替换。除了调用exec()的线程之外,其他所有线程都将立即消失。没有任何线程会针对线程特有数据执行结构函数,也不会调用清理函数。该进程的所有互斥量(为进程私有)和属于进程的条件变量都会消失。调用exec()之后,调用线程的线程ID是不确定的。

线程和fork

当多线程进程调用fork()时,仅会将发起调用的线程复制到子进程中。子进程中该线程的线程ID与父进程中发起fork()调用线程的线程ID相一致(后面会有例子说明)。其他线程均在子进程中消失,也不会为这些线程调用清理函数以及针对线程特有数据的解构函数。这将导致如下一些问题。

  • 虽然只将发起调用的线程复制到子进程中,但全局变量的状态以及所有的Pthreads对象(如互斥量、条件变量等)都会在子进程中得以保留。(因为在父进程中为这些Pthreads对象分配了内存,而子进程则获得了该内存的一份拷贝。)这会导致很棘手的问题。例如,假设在调用fork()时,另一线程已然锁定了某一互斥量,且对某一全局数据结构的更新也做到了一半。此时,子进程中的该线程无法解锁这一互斥量(因为其并非该互斥量的属主),如果试图获取这一互斥量,线程会遭阻塞。此外,子进程中的全局数据结构拷贝可能也处于不一致状态,因为对其进行更新的线程在执行到一半时消失了。
  • 因为并未执行清理函数和针对线程特有数据的解构函数,多线程程序的fork()调用会导致子进程的内存泄露。另外,子进程的线程很可能无法访问(父进程中)由其他线程所创建的线程特有数据项,因为(子进程)没有相应的引用指针。

由于这些问题,推荐在多线程程序中调用fork()的唯一情况时:其后紧跟对exec()的调用。因为新程序会覆盖原有内存,exec()将导致子进程的所有Pthreads对象消失。对于那些必须执行fork(),而其后又无exec()跟随的程序来说,Pthreads API提供了一种机制:fork处理函数。可以利用函数pthread_atfork来创建fork处理函数。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>	   
#include <unistd.h>
#include <pthread.h>

void *handle1(void *arg)
{
	printf("handle1 tid = %d\n", pthread_self());
	
	pid_t childpid = fork();
	switch (childpid)
	{
	    case -1:
		{
		    perror("fork()");
			exit(EXIT_FAILURE);
		}
		case 0:
		{
			printf("fork tid = %d\n", pthread_self());
			_exit(EXIT_SUCCESS);
		}
		default:
		{
		    exit(EXIT_SUCCESS);
		}
	}
}

void *handle2(void *arg)
{
	printf("handle2 tid = %d\n", pthread_self());
	
	return NULL;
}

int main(int argc, char *argv[])
{
	pthread_t tid1, tid2;
	pthread_create(&tid1, 0, handle1, NULL);
	pthread_create(&tid2, 0, handle2, NULL);
	
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
}

输出信息:

handle1 tid = 1084647760
handle2 tid = 1109567824
fork tid = 1084647760

可以看到,fork的tid和线程一的相同

 

线程和exit()

如果任何线程调用了exit(),或者主线程执行了return,那么所有线程都将消失,也不会执行线程特有数据的解构函数以及清理函数。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值