Linux进程之通过系统调用创建进程[fork()函数]

文章目录

  • 0.PID是什么?
  • 1.通过代码创建子进程--fork
    • 1.1fork()初识
    • 1.2通过系统调用创建进程
    • 1.3perror()函数的了解
  • 2.fork()的进一步了解
    • 2.1通过代码了解
    • 2.2查看进程的指令

0.PID是什么?

  • 进程PID(Process ID)是操作系统为每个正在运行的进程分配的唯一标识符
  • PID是一个整数值,用于在操作系统中唯一标识一个进程。每当一个新的进程被创建时,操作系统会为其分配一个唯一的PID。
  • PID在操作系统中起到了重要的作用,它可以用来识别和管理进程
  • 操作系统可以通过PID追踪进程的状态、资源使用情况、与其他进程的关系
  • PID还可以用于进程间通信、进程调度、资源分配等操作。
  • 在Linux中,进程PID的数据类型是pid_t,它定义在<sys/types.h>头文件中。pid_t类型是一个有符号整数类型[实际使用中,PID的值始终是非负整数]

1.通过代码创建子进程–fork

1.1fork()初识

在这里插入图片描述

输出
hello linux!
i love you!

int main()
{
printf("hello linux!\n);
printf("i love you!\n);
return 0;
}

输出
hello linux!
i love you!
i love you!

int main()
{
printf("hello linux!\n");
fork();
printf("i love you!\n");
return 0;
}

输出
hello linux!
ret = xxx
ret = 0

int main()
{
printf("hello linux!\n");
pid_t ret = fork();
printf("ret = %d\n", ret);
return 0;
}

1.2通过系统调用创建进程

在这里插入图片描述
在这里插入图片描述

成功 在父进程中返回子进程的PID,在子进程中返回0
失败 在父进程中返回-1,不创建子进程,适当设置errno

在这里插入图片描述
在这里插入图片描述

1.3perror()函数的了解

在这里插入图片描述

了解

  1. 打印与最近的错误代码相关的错误消息
  2. perror() 函数接收一个字符串参数 s,可以是自定义的错误提示信息
  3. 根据全局变量 errno 中保存的错误代码,将错误消息输出到标准错误流(stderr)

perror()函数的使用

  1. 在可能出错的操作后显示调用perror()函数
  2. perror()函数会检查 errno 的值,errno 是一个宏定义的全局变量,表示最近发生错误的错误代码
  3. 如果 errno 的值表示出现了错误,perror() 函数将根据 errno 的值输出相应的错误消息

举例:

    FILE *pfile = fopen("file.txt", "r");
    if (file == NULL)
    {
        perror("fopen");//输出: fopen: ...............
        return 1;
    }

2.fork()的进一步了解

2.1通过代码了解

  1. fork()之后 代码是父子共享的
  2. 虽然共享 但是通过if else 不一定都能执行 共享 != 能执行
int main()
{
pid t id = fork();
if(id< 0)
{
//创建失败perror ("fork") ;
return 1;
}
else if(id == 0)
{
//child process(task)
}
else
{
//parent process
}
printf("you can see me! n") ;
sleep(1);
return 0;
}

2.2查看进程的指令

1. 
ps axj  | head -1 && ps axj | grep test | grep -v grep
查看系统所有进程的信息只显示标题行
查看系统所有进程的信息只显示包含可执行程序test的内容
grep test 也是一个进程 为了显示只观 不显示 grep test 进程
2. 持续监控指定进程的脚本:
while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; echo "分隔符"; sleep 1; done

对下面代码的认识

  1. fork()之后有两个执行流 即两个进程
  2. 由此实现了两个死循环同时执行
  3. 以及if()else if() 同时执行 实际上是两个进程 判断了两次
int main()
{
pid t id = fork();
{
if(id< 0)
//创建失败
perror("fork") ;
return 1;
}
else if(id == 0)
{
//child process(task)while(1)
printf("I am child, pid: %d, ppid: %d\n", getpid(), getppid());
sleep(1);
}
else
{
//parentprocesswhile(1)
printf("I am father,pid: %d, ppid: %d\n", getpid(), getppid());
sleep(1);
}
return 0;
}

fork()函数返回值的认识

  1. 把子进程的pid返给父进程
  2. 把0返给子进程
  3. 父进程 : 子进程 == 1 : 0
  4. 把子进程的pid返给父进程 是为了让父进程能够对多个子进程进行管理

为何fork()函数会有两个函数值???

  1. fork()函数是OS提供的系统接口
  2. 一个新的进程被创建 实际上就是OS多了一个进程
  3. 我们已知 每多一个进程 我们就要做相关的工作: a. 拷贝代码和数据至内存 b.建立PCB结构体
  4. 新进程的PCB实际上以父进程的PCB为模板 大部分相同 少部分是自己独有的 比如PID

在这里插入图片描述

当fork()函数return后 核心代码执行结束了吗? 答案是: 已经执行完了

在这里插入图片描述

  1. 进程的调度: 在task_struct的队列中依据调度算法选择一个进程
  2. 操作系统和cpu运行某一个进程,本质是从task_struct 形成的运行队列中按照调度算法挑选一个task_struct 来执行它的代码
  3. 把进程与进程对于的PCB–task_struct联系起来

进程列表是什么?

进程表:进程表是操作系统中的数据结构,用于组织记录系统中所有进程的PCB。每个进程都有一个对应的进程表项(PCB),包含进程的标识符、状态、优先级、资源使用情况等信息。进程表可以用于管理和调度进程,操作系统可以根据进程表中的信息对进程进行分配资源、切换上下文等操作。

为什么会出现两个返回值?

  1. 子进程是在当前进程即父进程创建出来的
  2. 当子进程创建完 fork()函数准备return 之前 此时子进程已经被创建 当OS调度父进程时 父进程接收到的fork()函数的返回值id是已经创建好的子进程的pid 当子进程被调度 子进程接收到的fork()函数的返回值id是0 因为return id;语句被执行了两次 且是不同的值 所以才有了两个返回值的现象
  3. fork()函数内部 父子进程执行各自的return语句
  4. 返回两次 并不意味id有两个值

父子进程创建出来 谁先被运行呢?答案: 不一定

  1. 谁先运行不一定 由OS的调度器决定
  2. 比如: 当父进程执行了10ms 因为某些原因 父进程被放到运行队列的后面 OS又去执行子进程了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/139482.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0基础学习VR全景平台篇第120篇:极坐标处理接缝 - PS教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 紧跟上节课&#xff0c;我们已经学会了怎么利用PS蒙版工具来对航拍全景图补天。但是在后续工作学习中&#xff0c;我们会遇到天空这部分存在部分接缝的问题&#xff0c;如图&…

ZYNQ调试w25q128bv做flash启动系统

配置petalinux系统从flahs启动&#xff0c;发现BOO.BIN能启动&#xff0c;BOOT.BINimage.ub启动不了。其中烧写和配置的时候&#xff0c;image.ub.bin偏移地址都是0x520000 烧写&#xff0c;然后启动 U-Boot 2018.01-00083-gd8fc4b3b70 (Nov 13 2023 - 03:29:36 0000) Xilinx…

【unity】常用属性特征

编辑器功能 AddComponentMenu-添加组件菜单 将脚本添加到Unity编辑器的菜单中&#xff0c;方便开发者在编辑器中快速添加组件。 示例 using UnityEngine; [AddComponentMenu("添加组件/FollowTransform")] public class FollowTransform : MonoBehaviour { }效果 …

Seaborn数据可视化综合应用Basemap和Seaborn在线闯关_头歌实践教学平台

Seaborn数据可视化综合应用Basemap和Seaborn 第1关 Seaborn第2关 Seaborn图形介绍第3关 Basemap 第1关 Seaborn 任务描述 本关任务&#xff1a;编写一个绘制每个月销售总额的折线图。 编程要求 本关的编程任务是补全右侧上部代码编辑区内的相应代码&#xff0c;根据输入文件路…

java语言开发B/S架构医院云HIS系统源码【springboot】

医院云HIS全称为基于云计算的医疗卫生信息系统( Cloud- Based Healthcare Information System)&#xff0c;是运用云计算、大数据、物联网等新兴信息技术&#xff0c;按照现代医疗卫生管理要求&#xff0c;在一定区域范围内以数字化形式提供医疗卫生行业数据收集、存储、传递、…

基于若依的ruoyi-nbcio流程管理系统增加流程设计器支持自定义表单的选择与处理

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 因为之前不支持在流程设计器进行自定义业务表单的关联选择&#xff0c;所以这部分实现这个。 1、前端 对…

ZooKeeper+Kafka+ELK+Filebeat集群搭建实现大批量日志收集和展示

大致流程&#xff1a;将nginx 服务器&#xff08;web-filebeat&#xff09;的日志通过filebeat收集之后&#xff0c;存储到缓存服务器kafka&#xff0c;之后logstash到kafka服务器上取出相应日志&#xff0c;经过处理后写入到elasticsearch服务器并在kibana上展示。 一、集群环…

lora微调模版

lora微调模版 1、版一&#xff1a;使用peft包的lora微调&#xff08;1&#xff09;设置超参方式一&#xff1a;代码中设置&#xff08;便于debug&#xff09;方式二&#xff1a; .sh文件指定 &#xff08;2&#xff09;加载数据集I、对应的.jsonl或json文件, 原始格式为&#x…

Kafka简单汇总

Kafka的结构图 多个Parttion共同组成这个topic的所有消息。每个consumer都属于一个consumer group&#xff0c;每条消息只能被consumer group中的一个Consumer消费&#xff0c; 但可以被多个consumer group消费。即组间数据是共享的&#xff0c;组内数据是竞争的。二、消费模型…

PO设计模式详解(Python+selenium+unittest)

一、什么是PO设计模式&#xff08;Page Object Model&#xff09; 1、Page Object是一种设计模式&#xff0c;它主要体现在对界面交互细节的封装上&#xff0c;使测试用例更专注于业务的操作&#xff0c;从而提高测试用例的可维护性。 2、一般PO设计模式有三层 第一层&#…

【紫光同创国产FPGA教程】【PGC1/2KG第六章】密码锁实验例程

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGC1/2KG开发平台&#xff08;盘古1K/2K&#xff09; 一&#xff1a;盘古1K/2K开发板&#xff08;紫光同创PGC…

Git图形化界面GUI的使用SSH协议及idea集成Git

前言 图形化界面&#xff08;GUI&#xff0c;Graphical User Interface&#xff09;是一种用户与计算机程序或操作系统交互的方式&#xff0c;通过图形元素&#xff0c;如图标、按钮、窗口等&#xff0c;而不是通过命令行来完成操作。GUI的设计旨在让用户通过直观的图形界面进行…

MAC地址注册的原理和应用

MAC地址注册是指在网络设备中&#xff0c;将设备的物理地址&#xff08;即MAC地址&#xff09;与设备的IP地址进行关联和注册的过程。MAC地址是以太网卡硬件上的独特标识符&#xff0c;用于在局域网中标识网络设备。 MAC地址注册在网络管理中起到重要作用&#xff0c;它可以帮助…

vue3配置环境变量,小白简单易学

环境变量的意义就是防止我们更新打包的时候写错变量&#xff0c;合并代码这些一系列问题 首先看看效果 左边是本地测试环境&#xff0c;右边是打包后的生产环境&#xff0c;写这个环境变量的好处就是&#xff0c;你在本地开发的时候变量随便改&#xff0c;不会影响生产环境&am…

ChIP在植物领域中的应用

01 什么是ChIP&#xff1f; 染色质免疫共沉淀技术&#xff08;Chromatin Immunoprecipitation assay&#xff0c;ChIP&#xff09;是研究体内DNA与蛋白质相互作用的方法。其基本原理是在细胞生理状态下固定蛋白质-DNA复合物&#xff0c;将其随机打断为一定长度范围内的染色质小…

阿里云容器镜像服务的运维总结

一、背景 容器镜像服务&#xff0c;作为一个可选付费产品&#xff0c;主要作用是存储docker的镜像仓库&#xff0c;供k8s拉取到Pod节点里。 你可以自己搭建一个harbor镜像仓库&#xff0c;在公司的开发环境下&#xff0c;将image推送到仓库&#xff1b;然后在生产k8s从仓库拉取…

基于JAX-WS实现RESTful形式的web服务端点(endpoint)

RESTful形式的web服务使用XML/HTTP绑定&#xff0c;实现jakarta.xml.ws.Provider。 服务端的实现类用jakarta.xml.ws.WebServiceProvider和BindingType(valueHTTPBinding.HTTP_BINDING)注释。其中HTTPBinding.HTTP_BINDING表示使用XML/HTTP绑定。 例如&#xff1a; WebServic…

Cesium 点线面实体

1.点 const point viewer.entities.add({ id: point, position: Cesium.Cartesian3.fromDegrees(113, 30), point: { pixelSize: 20, //像素 color: Cesium.Color.DEEPPINK, outlineColor: Cesium.Color.fromCssColorString(#fff), outlineWidth: 2, // 像素 }, }); 2.图标标注…

10 # 手写 every 方法

every 使用 every() 方法测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。 ele&#xff1a;表示数组中的每一个元素index&#xff1a;表示数据中元素的索引array&#xff1a;表示数组 <script>var arr [1, 3, 5, 7, 8];var result arr.ever…

EDA实验-----3-8译码器设计(QuartusII)

目录 一. 实验目的 二. 实验仪器 三. 实验原理及内容 1.实验原理 2.实验内容 四&#xff0e;实验步骤 五. 实验报告 六. 注意事项 七. 实验过程 1.创建Verilog文件&#xff0c;写代码 ​编辑 2.波形仿真 3.连接电路图 4.烧录操作 一. 实验目的 学会Verilog HDL的…
最新文章