fork多线程中需要注意的问题

本文介绍了在Linux系统中,fork调用如何处理多线程场景。在多线程进程中,只有调用fork的当前线程会被复制到子进程中,其他线程无法感知到这一变化。由于锁资源也会被复制,可能导致子进程中出现锁的状态问题。通过pthread_atfork函数可以在fork前后执行特定操作,避免锁资源的冲突,确保子进程的初始化状态正确。
摘要由CSDN通过智能技术生成

单线程场景

对于fork系统调用,我们知道是linux下创建子进程的一种方式。fork调用一次,对于程序看来,是“返回两次”。这里其实理解为fork调用中,已经创建出了子进程,父子进程分别分从fork调用中返回。父进程需要知道子进程的进程ID,所以返回值大于0的是父进程,而子进程返回0即可,子进程可以通过getpid获取自身进程ID和getppid获取父进程ID。

多线程场景

对于多线程场景中,例如一个10个线程的进程中。如果某个线程调用了fork,新的子进程中会有多少个线程?请思考30秒。
正确答案是:直接man fork即可看到。

Note the following further points:
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只复制当前线程

试想,如果多个线程都被复制到了子进程中,除了当前线程能通过fork返回值判断,其他线程怎么感知到自己被复制到了子线程呢?从逻辑上就比较容易推断出,这种多线程同时复制到子进制的fork方案是不合理的。

锁资源

锁资源例如mutex,同样也是会被复制到子进程中。那么就会出现一种情况,当前线程的mutex的状态被复现到了子进程中。如果mutext是被加锁状态,则在子进程如果尝试对mutext进行加锁的时候,会导致子锁的产生。如下代码所示:

#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *fun(void *arg)
{
   
    printf("pid = %d begin doit ...\n", static_cast<int>(getpid()));
    pthread_mutex_lock(&mutex);
    struct timespec ts = {
   2, 0};
    nanosleep(&ts, NULL);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值