当前位置: 首页 > article >正文

Linux运用fork函数创建进程

fork函数:

函数原型:

pid_t fork(void);

父进程调用fork函数创建一个子进程,子进程的用户区父进程的用户区完全一样,但是内核区不完全一样;如父进程的PID和子进程的PID不一样。

返回值:

RETURN VALUE
       On success, the PID of the child process is returned in the parent, and
       0  is returned in the child.  On failure, -1 is returned in the parent,
       no child process is created, and errno is set appropriately.

父进程返回的是子进程的PID,这个值大于0。

子进程返回的是0。

注意:一个进程只能返回一个值,父子进程各自返回一个值。

父进程执行pid>0的逻辑,子进程执行pid==0的逻辑;

父子进程谁先执行:谁先抢到cpu时间片,谁先执行。

这是fork.c文件:

通过fork函数创建了一个子进程。

pid也获得了两个值,一个大于零(父进程),一个等于零(子进程)。

两个进程都会执行下面的语句。

父进程执行时,pid>0,会打印出"father:pid==[%d]\n"

子进程执行时,pid=0,会打印出"child:pid==[%d]\n"

在父进程处加sleep(1)是防止父进程比子进程提前结束,让子进程变成孤儿进程。

执行后:

 去掉sleep后有两种结果,一种是子进程先结束:

一种是父进程先结束,子进程变孤儿进程,返回命令句:

如何创建兄弟进程 :

通过以上操作创建的子进程不是全部是兄弟进程,就创建出七个子进程(子进程也会创建子进程)。我们可以添加break;如果是子进程,就跳出循环,不让他创建自己的子进程。

再添加以下操作就可以知道是第几个进程

父进程中i会增到3,所以i==3时是父进程。

完整代码:

#include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 int main()
  7 {
  8 
  9     //pid_t fork(void);
 10     int i=0;
 11     for(;i<3;i++)
 12     {
 13         pid_t pid=fork();
 14         if(pid<0)
 15         {
 16             perror("fork error");
 17             return -1;
 18         }
 19         else if(pid>0)
 20         {
 21             printf("father:pid==[%d],fpid==[%d]\n",getpid(),getppid());
 22             //sleep(1);
 23         }
 24         else if(pid==0)
 25         {
 26             printf("child:pid==[%d],fpid==[%d]\n",getpid(),getppid());
                break;
 27         }
 28         //  else if(pid>0)
 29         //  {
 30         //      printf("father:pid==[%d]\n",getpid());
 31         //  }
 32     }
 33     if(i==0)
 34     {
 35         printf("[%d]----[%d]:child\n",i,getpid());
 36     }
 37     if(i==1)
 38     {
 39         printf("[%d]----[%d]:child\n",i,getpid());
 40     }
 41     if(i==2)
 42     {
 43         printf("[%d]----[%d]:child\n",i,getpid());
 44     }
 45     if(i==3)
 46     {
 47         printf("[%d]----[%d]:father\n",i,getpid());
 48       }
 49     return 0;
 50 }
               

 结果:

 父子进程不能共享全局变量:

但是父子进程只是对全局变量做读操作,则父子进程在内存中只有一份,属于共享。

但是父子进程中任何一个进程对该全局变量做修改操作,会在内存中拷贝一个副本,然后在这个副本上进行修改,修改完成以后映射回去。--写时复制(拷贝),读时共享

验证:

在pid==0(子进程)时加上sleep(1),是为了避免父进程还没有执行,子进程就已经结束。

结果:

结果发现子进程中val==9,由此当父进程修改val的值时,父子进程不再共享全局变量。 


http://www.kler.cn/news/232855.html

相关文章:

  • Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(一)
  • 教你用C++开发 身份证号码日期提取工具
  • 除夕快乐(前端小烟花)
  • 【C++ 二分】电脑游戏
  • 聊聊JIT优化技术
  • Android9~Android13 某些容量SD卡被格式化为内部存储时容量显示错误问题的研究与解决方案
  • 贪心算法入门题(算法村第十七关青铜挑战)
  • Get Ready!这些 ALVA 应用即将上线 Vision Pro!
  • C语言:分支与循环
  • nodejs+vue高校实验室耗材管理系统_m20vy
  • 探索XGBoost:参数调优与模型解释
  • 【网工】华为设备命令学习(服务器发布)
  • 程序设计语言之机器语言、汇编语言、高级语言
  • 【制作100个unity游戏之24】unity制作一个3D动物AI生态系统游戏3(附项目源码)
  • 《Docker极简教程》--Docker环境的搭建-在Windows上搭建Docker环境
  • Elasticsearch 安装和配置脚本文档
  • UE4运用C++和框架开发坦克大战教程笔记(十九)(第58~60集)完结
  • 通俗易懂:快速排序算法全解析
  • TCP/IP协议以及UDP(超详细,看这一篇就够了)
  • Docker配置Portainer容器管理界面
  • StarRocks 1 月社区动态(2024)
  • Android AOSP源码研究之万事开头难----经验教训记录
  • 强化学习 | 基于 Q-Learning 算法解决 Treasure on Right 游戏
  • 分享90个行业PPT,总有一款适合您
  • Linux 命令行的世界 :2.文件系统中跳转
  • Transformer的PyTorch实现之若干问题探讨(二)
  • Linux的可移植性
  • 【FFmpeg】ffplay 命令行参数 ⑤ ( 设置音频滤镜 -af 参数 | 设置统计信息 -stats 参数 | 设置同步时钟类型 -sync 参数 )
  • 第60讲公共Tabs组件封装
  • MQTT 服务器(emqx)搭建及使用