linux进程高级属性之安全的fork

linux进程高级属性之安全的fork

安全性问题:当线程调用fork函数时,就为子进程创建了整个进程地址空间的副本,子进程通过继承整个地址空间的副本,也会将父进程的互斥量、读写锁、条件变量的状态继承过来。也就是说,如果父进程中互斥量是锁着的,那么在子进程中互斥量也是锁着的(尽管子进程自己还没有来得及lock),这是非常不安全的,因为子进程中拥有锁的线程也许已经消失,只会保留fork的那个线程。

解决办法:

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

它会注册三个函数: prepare是在fork调用之前会被调用的,parent在fork返回父进程之前调用,child在fork返回子进程之前调用。如果在prepare中加锁所有的互斥量,在parent和child中解锁所有的互斥量,那么在fork返回之后,互斥量的状态就是未加锁。

实例:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
pthread_mutex_t mutex;
void prepare(void)
{
	pthread_mutex_lock(&mutex);
	printf("this is prepare process!\n");
}
void parent(void)
{
	printf("this is parent process!\n");
	pthread_mutex_unlock(&mutex);
}
void child(void)
{
	printf("this is child process!\n");
	pthread_mutex_unlock(&mutex);
}
void * thread_f(void *arg)
{
	printf("this is thread_f\n");
	pid_t pid;
	pthread_atfork(prepare,parent,child);
	pid = fork();
	if(pid == 0)
	{
		pthread_mutex_lock(&mutex);
		printf("child process!\n");
		pthread_mutex_unlock(&mutex);
	}
	if(pid >0)
	{
		pthread_mutex_lock(&mutex);
		printf("parent process\n");
		pthread_mutex_unlock(&mutex);
	}
	return (void *)0;
 
}
 
int main(int argc,char *argv[])
{
	pthread_t ntid;
	int err,num;
	err = pthread_create(&ntid,NULL,thread_f,NULL);
	if(err!=0)
	{
		printf("Creat new thread fail\n");
		return -1;
	}
	pthread_mutex_init(&mutex,NULL);
	pthread_mutex_lock(&mutex);
	sleep(1);
	pthread_mutex_unlock(&mutex);
	pthread_join(ntid,NULL);
	return 0;
}

运行结果:

$ gcc -pthread pthread_fork.c
$ ./a.out
this is thread_f
this is prepare process!
this is parent process!
parent process
this is child process!
child process!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值