ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux C/C++——fork()函数基础

2020-09-21 20:33:30  阅读:279  来源: 互联网

标签:fork pid C++ Linux 进程 返回值 include ID


一、定义   1.fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器,在父进程中使用的相同打开文件。 它不需要参数并返回一个整数值。下面是fork()返回的不同值。            负值:创建子进程失败。            零:返回到新创建的子进程。            正值:返回父进程或调用者。该值包含新创建的子进程的进程ID。   2.所要用到的头文件有:     #include<sys/types.h>     #include<unistd.h>   3.说明:     ——父、子进程完全一样(代码、数据),子进程从fork内部开始执行,fork返回子进程的pid后,接着执行下一条语句。     ——该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是子进程的ID。     ——一般来说,在fork之后是父进程先执行还是子进程先执行是取决于内核锁使用的调度算法。   4.示例代码(一)——这段程序通过fork函数不同的返回值来验证不同的进程在运行,同时通过一些全局变量和局部变量来看到父子进程之间的继承关系。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int galbol = 6;//定义全局变量
char buf[] = "Hello Linux";//定义一个字符串
int main(){
    int var = 88;//定义一个局部变量
    pid_t  pid;//(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)
    puts(buf);//输出字符串
    pid = fork();//执行fork函数并把返回值赋给pid
    if (pid < 0)//如果返回值小于0,则创建失败
    {
        printf("error\n");
        exit(0);
    }
    
    if (pid == 0)//返回值等于0,表示创建成功,是子进程运行
    {
        printf("This is children process!\n");
        galbol++;
        var++;
    }
    else          //如果返回ID就是父进程
    {
        printf("This is parent process\n");
    }
    printf("pid=%d,ppid=%d,galbol=%d,var=%d\n",getpid(),getppid(),galbol,var);//用来测试的变量
    return 0;
}

运行结果

讲解一下运行结果,首先输出了"Hello Linux!",这是我们放在创建进程之前的一个输出,接着创建一个进程,返回值是ID,则表明当前是父进程,接着输出几个变量,当前进程ID和父进程ID,变量galbol和val,由于在父进程中没有对两个变量的值进行修改,所以两个变量的值未发生改变。那接下来就是子进程,返回值是0,输出自己是子进程,然后执行子进程的代码,可以看到子进程的pid=5263,父进程ID=5983,刚好等于前面父进程的ID,并且修改了两个变量的值。

  5.示例代码(二)——这次的demo是在父进程中打开一个文本文件,并进行读操作,再看创建的子进程能否也读取与父进程一样的文本文件。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
char str[10];       //定义一个数组,用来测试
int  main() {
    FILE *fp;       //fp文件指针
    pid_t  pid;     //进程号
    pid = fork();
    fp = fopen("a.txt","r");   //以只读的方式打开文件
    if (fp == NULL)
    {
        printf("Open error!");  //如果指针返回的值为NULL,则打开失败
        exit(0);
    }
    else
    {
        if(pid < 0)             //fork返回值小于0,创建失败
        {
            printf("Error!\n");
            exit(0);
        }
        else if (pid == 0)      //fork等于0,返回到新建的子进程
        {
            fread(str,sizeof(char),2,fp);  //读两个字符,并输出到屏幕
            puts(str);
        } 
        else                  //否则返回到父进程
        {
           sleep(2);
           fseek(fp,2L,SEEK_SET);  //定位到子进程读取的两个字符之后开始
           fread(str,sizeof(char),3,fp);//读取三个字符
           puts(str);
        }
    }
    
    return 0;
}

这是a.txt里面的内容

这是运行结果

可以看到,子进程打开了与父进程一样的文本文件。

  6.总结一下:使用fork函数得到的子进程从父进程处继承了整个进程的地址空间,包括进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等

标签:fork,pid,C++,Linux,进程,返回值,include,ID
来源: https://www.cnblogs.com/953-zjf/p/13703716.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有