fork的注意事项

17 篇文章 0 订阅

在fork是需要注意父进程中的哪些资源是会被子进程继承的

用于管理动态内存和文件描述符的RAII类可以正常工作

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h> // open

pid_t g_parent_pid = 0;

#define NEW_BUF_SIZE  6


// 子进程会继承地址空间和文件描述符

struct A
{
    char *m_pBuf; //动态内存
    int m_fd; // 文件描述符会被子进程继承
    A()
    {
        m_pBuf = new char[NEW_BUF_SIZE] {0};
        char buf[] = "hello";
        strcpy(m_pBuf, buf);
        m_fd = open("./test.txt", O_RDWR | O_CREAT, 0666);
        printf("A() , pBuf:%p, m_fd=%d\n", m_pBuf, m_fd);
    }

    ~A()
    {
        printf("pid=%d, ~A(), pBuf:%p, m_fd=%d, m_pBuf:%s\n", getpid() , m_pBuf, m_fd, m_pBuf);
        bzero(m_pBuf, NEW_BUF_SIZE);
        delete m_pBuf;
        m_pBuf = nullptr;
        close(m_fd);
    }

    void dosomething()
    {
        if(g_parent_pid == getpid())
        {
            sleep(5);
        }

        char buf[] = "hello";
        write(m_fd, buf, sizeof(buf) );
        printf("pid:%d, do something...., m_fd=%d, m_pBuf=%s\n", getpid(), m_fd, m_pBuf);
        strcpy(m_pBuf, "hello world");
    }
};

int main()
{
    A a ;
    printf("i'm parent process!\n");
    g_parent_pid = getpid();
    pid_t pid = fork();
    a.dosomething();
    printf("i'm very happy.\n");

    return 0;  // ~A() 被调用了两次: 父进程和子进程各一次
    
}

注意子进程不会继承:

  • 父进程的内存锁: mlock(2) , mlockall(2)
  • 父进程的文件锁: fcntl(2) , 但是会继承 fcntl(2)打开的文件文件 和 父进程中的flock(2)
  • 父进程的某些定时器: settimer(2), alarm(2), timer_create(2)
  • pending signal ( sigpending(2))
  • 信号量(semop(2))
  • CPU计数器
  • 异步IO操作(aio_read(3), aio_write(3) , 和 异步IO的context

思考: 下面程序一共有多少个进程(包括main进程)?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>


int main()
{
    fork();
    fork() && fork() || fork();
    fork();

    // g_num ++ ;
    // printf("num =%d\n", g_num);

    // 此处会阻塞等待输入,  此时可以在另外的终端通过以下命令查看
    // ps aux | grep a.out | grep -v grep | wc -l
    getchar(); 
    return 0;
}







// int g_num = 0;

// pid_t myfork()
// {
//     pid_t pid = fork();
//     if(0 == pid )
//     {
//         printf("=\n");
//     }
//     return pid;
// }


// int main()
// {
//     myfork(); 
//     myfork() && myfork() || myfork(); 
//     myfork();

//     g_num ++ ;
//     // printf("num =%d\n", g_num);
//     return 0;
// }



// fork() && fork() || fork();
/*
pid =  fork()
if(pid > 0)
{
    if(0 == fork() )
    {
        fork()
    }
}
else if(pid == 0)
{
    fork()
}
*/



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值