fork函数小结

本文介绍了Unix系统中使用fork系统调用创建新进程的方法,包括子进程与父进程的区别及如何通过fork实现进程间变量独立。此外,还探讨了fork调用后父进程与子进程共享文件描述符的特性及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Unix系统中,只有一个系统调用可以用来创建新进程:fork。

由fork创建的新进程被称为子进程。fork函数被调用一次,但返回2次。2次返回的区别是子进程的返回值是0,而父进程的返回值是新创建的额子进程的进程ID。
子进程和父进程继续执行fork调用之后的指令。子进程是父进程的副本。例如,子进程获得父进程数据空间、堆和栈的副本。注意,这是子进程所拥有的副本。父进程和子进程并不共享这些存储空间。

例如

#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    int n=0;;
    pid_t pid;

    if((pid=fork())<0)
    {
        fprintf(stderr,"fork error:[%s]\n",strerror(errno));
        exit(1);
    }
    else if(pid>0)      //父进程
    {     
        sleep(2);       //为了保证子进程先执行,父进程睡眠2s
    }
    else                //子进程
    {
        n++;
    }
    printf("pid = %ld, n = %d\n",(long)getpid(),n);
    exit(0);
}

运行的结果为
这里写图片描述

可以看到,子进程的变量值改变了,父进程的变量值没有改变

文件共享

fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中。我们说“复制”是因为对每个文件描述符来说,就好像执行了dup函数。父进程和子进程每个相同的打开描述符共享同一个文件表项。
这里写图片描述

重要的一点是, 父进程和子进程共享同一个文件偏移量。考虑下述情况: 一个进程fork了一个子进程, 然后等待子进程终止. 假定,作为普通处理的一部分, 父进程和子进程都向标准输出进行写操作。如果父进程的标准输出己重定向(很可能是由shell实现的), 那么子进程写到该标准输出时, 它将更新与父进程共亭的该文件的偏移量. 在这个例子中, 当父进程等待子进程时, 子进程写到标准输出:而在子进程终止后, 父进程也写到标准输出上, 并且知道其输出会追加到子进程所写数据之后。如果父进程和子进程不共享同一文件偏移量,要实现这种形式的交互就要困难得多。

#include<unistd.h>
#include<stdio.h>
#include<sys/wait.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>

#define MAXLEN 1024

int main()
{
    int n;
    int fd[2];
    pid_t pid;
    char buf[MAXLEN];
    int file_fd;
    file_fd=open("test.txt",O_RDWR|O_CREAT|O_TRUNC);   //打开一个文件

    if((pid=fork())<0)
    {
        fprintf(stderr,"fork error:[%s]\n",strerror(errno));
        exit(1);
    }
    else if(pid>0)
    {
        sleep(2);
        write(file_fd,"parent:hello world\n",19);   //父进程写入
    }
    else
    {
        write(file_fd,"child:hello world\n",18);    //子进程写入
    }
    exit(0);
}

运行结果

这里写图片描述

可以看到,父进程的写入的数据在子进程写入的数据之后。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值