mysql master线程 fork_fork多线程进程

本文详细探讨了Linux系统中fork函数如何处理多线程进程。根据man fork手册,子进程仅复制调用fork的线程,而不包括其他线程。通过代码示例验证了这一行为,并展示了当在非主线程中调用fork时,子进程只会执行fork所在线程的代码。此外,文章还讨论了fork过程中锁的状态复制,举例说明了如果锁在fork时被锁定,子进程会继承这一状态,可能导致子进程因无法获取锁而阻塞。
摘要由CSDN通过智能技术生成

问题

在linux系统中,我们都知道fork会产生一个调用进程的复制,创建出一个新的进程,那么如果父进程有多个线程会不会复制父进程的多个线程呢?

解答

使用man fork指令查看手册其实就能找到答案,关键的一段如下

The child process is created with a single thread—the one that

called fork(). The entire virtual address space of the parent is

replicated in the child, including the states of mutexes, condition

variables, and other pthreads objects; the use of pthread_atfork(3)

may be helpful for dealing with problems that this can cause.

其中第一句话翻译过来就是子进程创建出来时只有一个线程,就是调用fork()函数的那个线程。

验证

我们可以用如下代码验证一下:

#include

#include

#include

#include

void * func1(void * args){

while(1){

printf("func1\n");

}

}

int main(){

pthread_t tid;

pthread_create(&tid, NULL, func1, NULL);

pid_t pid = fork();

// 子进程

if(pid==0){

int t = 5;

while(t-->0){

sleep(1);

printf("child process\n");

}

}

return 0;

}

代码执行结果如下:

9f1b052bfe78ef76dfee0ff3cde2bea4.png

可以看到子进程在等待的时候并输出"child process"的时候,父进程创建的线程的函数并没有输出。

那么如果我们不是在主线程中fork,而是在创建出的线程中fork呢?代码如下:

#include

#include

#include

#include

void * func1(void * args){

// fork()出一个子进程

pid_t pid = fork();

// 父进程退出

if(pid > 0) return NULL;

while(1){

sleep(1);

printf("func1:my pid = %d\n", getpid());

}

}

int main(){

pthread_t tid;

pthread_create(&tid, NULL, func1, NULL);

// 等待fork()完成

sleep(1);

while(1){

sleep(1);

printf("main :my pid = %d\n", getpid());

}

return 0;

}

执行结果如下:

cd729a0790af9d796d9d7cdde31b0d8c.png

可以看到结果中子进程只执行了fork()时所在的func1函数,而没有继续执行main函数中的指令,也证实了fork的子进程中只产生了fork所在的线程,而没有产生其它线程。

题外

我们注意手册中的这句话

The entire virtual address space of the parent is replicated in the child, including the states of mutexes, condition variables, and other pthreads objects;

也就是fork的时候会复制锁的状态,也就是说如果此时恰好某个锁被锁了,那么在fork产生的子进程中也是lock的状态。

用如下代码来验证一下:

#include

#include

#include

#include

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void * func1(void * args){

pthread_mutex_lock(&mutex);

printf("func1\n");

pthread_mutex_unlock(&mutex);

}

int main(){

pthread_t tid;

pthread_create(&tid, NULL, func1, NULL);

// sleep保证线程加锁完成才fork

sleep(1);

pid_t pid = fork();

// 子进程

if(pid==0){

int t = 5;

sleep(1);

while(t--){

// 子进程请求锁

pthread_mutex_lock(&mutex);

printf("child process\n");

sleep(1);

pthread_mutex_unlock(&mutex);

}

}

return 0;

}

程序执行结果:

4d9b740fdfb5553c12331e9a52117255.png

子进程进入想要锁的状态,但是没有后续输出,原因就是fork的时候mutex被锁住了,而子进程把mutex被锁的状态复制了,而又没有其它子线程来释放锁,所以一直请求不到锁阻塞在pthread_mutex_lock函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值