当前位置:   article > 正文

fork--创建进程_fork创建进程

fork创建进程

fork–创建进程

fork函数基本知识

pid_t fork(void)
返回值:
    在父进程中,成功的话返回子进程的pid,失败返回-1
    在子进程中,返回值pid为0
  • 1
  • 2
  • 3
  • 4

fork()函数将运行着的进程分裂出另一个子进程,它通过拷贝父进程的方式创建子进程。
子进程与父进程有相同的代码空间、文件描述符等资源 ,如下图所示:

image-20230811121236530

父、子进程的区别:

fork的返回值不一样,pid不同,ppid不同,未决信号集合文件锁不继承,资源利用量清0

进程创建后,子进程与父进程开始并发执行,谁先执行由内核调度算法来决定。

init进程:pid为1,所有进程的祖先。

代码示例

看下面的代码,观察父、子进程打印的结果

fork1.c

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


int main()
{
    //定义pid号
    pid_t pid;
    
    printf("[%d]:Begin!\n",getpid());
    
    //在调用fork前,调用!!!!
    //fflush(NULL);
    
    pid = fork();
    if(pid < 0)
    {
        perror("fork()");
        exit(1);
    }
    if(pid == 0) //child
    {
        printf("[%d]:Child is working!\n",getpid());
    }
    else		//parent
    {
        printf("[%d]:Parent is working!\n",getpid());
    }
    
  
    printf("[%d]:End!\n",getpid());
      
    
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

编译执行程序,父子进程的pid分别是9227和9228,如下图

image-20230810230422760

重新开启一个终端,使用如下命令,显示进程的关系

ps axf
  • 1

image-20230810231304778

从上图看出,(pid=9227)./fork1的进程创建了一个(pid=9228)的进程./fork1。(pid=9227)./fork1进程的父进程是bash,即上图中pid=8760

父、子进程的输出

输出到终端

我们重新编译代码,执行,输出的内容中,Begin!输出1次,见下图:

image-20230810232005185

输出到文件

执行程序的将输出重定向一个文件中,查看文件的内容,发现Begin!内容输出了2次

image-20230810232325611

同样一份代码,为何输出的内容有差异那?
是缓冲造成的。 终端是标准输出设备, 是行缓冲模式 ,printf语句中的\n是行缓冲作用,所以\n会刷新缓冲区。 如果重定向到文件, 文件的缓冲是全缓冲模式 \n就起不到刷新缓冲的作用,只是一个换行的作用

Begin!放到缓冲区中,还没来得及写到文件里面的时候,马上执行了fork函数,父、子进程的缓冲区各自有begin,所以会有两个。

如何解决,上面的问题
要在调用fork函数前,调用fflush(NULL)函数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/210079
推荐阅读
相关标签
  

闽ICP备14008679号