linux之pthread_atfork()函数讲解

linux之pthread_atfork()函数讲解

#include <pthread.h>
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));

pthread_atfork()在fork()之前调用,当调用fork时,内部创建子进程前在父进程中会调用prepare,内部创建子进程成功后,父进程会调用parent ,子进程会调用child。

直接看下代码:
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *arg)
{
    printf("pid = %d begin doit ...\n", static_cast<int>(getpid()));
    pthread_mutex_lock(&mutex);
    struct timespec ts = {2, 0};
    nanosleep(&ts, NULL);
    pthread_mutex_unlock(&mutex);
    printf("pid = %d end doit ...\n", static_cast<int>(getpid()));

    return NULL;
}

void prepare(void)
{
    pthread_mutex_unlock(&mutex);
}

void parent(void)
{
    pthread_mutex_lock(&mutex);
}

int main(void)
{
    pthread_atfork(prepare, parent, NULL);
    printf("pid = %d Entering main ...\n", static_cast<int>(getpid()));
    pthread_t tid;
    pthread_create(&tid, NULL, doit, NULL);
    struct timespec ts = {1, 0};
    nanosleep(&ts, NULL);
    if (fork() == 0)
    {
        doit(NULL);
    }
    pthread_join(tid, NULL);
    printf("pid = %d Exiting main ...\n", static_cast<int>(getpid()));

    return 0;
}

同样的流程,但在执行fork() 创建子进程之前,先执行prepare(), 将子线程加锁的mutex 解锁下,然后为了与doit() 配对,在创建子进程成功后,父进程调用parent() 再次加锁,这时父进程的doit() 就可以接着解锁执行下去。而对于子进程来说,由于在fork() 创建子进程之前,mutex已经被解锁,故复制的状态也是解锁的,所以执行doit()就不会死锁了。
执行结果如下:
simba@ubuntu:~/Documents/build/debug/bin$ ./deadlock_test2
pid = 4905 Entering main ...
pid = 4905 begin doit ...
pid = 4908 begin doit ...
pid = 4905 end doit ...
pid = 4905 Exiting main ...
simba@ubuntu:~/Documents/build/debug/bin$ pid = 4908 end doit ...
pid = 4908 Exiting main ...

simba@ubuntu:~/Documents/build/debug/bin$ 

可以看到子进程也正常退出了。


  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值