详解Linux的系统调用fork()函数

在Linux系统中,fork()是一个非常重要的系统调用,它的作用是创建一个新的进程。具体来说,fork()函数会在当前进程的地址空间中复制一份子进程,并且这个子进程几乎完全与父进程相同,包括进程代码、数据、堆栈以及打开的文件描述符等。因此,父进程和子进程之间的关系可以看作是一个“克隆”关系。

fork()函数的语法如下:

#include <unistd.h>  
pid_t fork(void);

其中,参数pid_t代表进程id,而fork()函数返回值则有以下两种情况:

  • 如果返回0,表示当前进程是子进程。
  • 如果返回一个正整数,表示当前进程是父进程,并且返回的整数就是新创建出来的子进程的进程ID。

此外,如果fork()返回值为-1,表示创建子进程失败。

fork()函数的本质是在内核中创建一个新的进程控制块(PCB),然后将原来进程的PCB中的大部分内容都复制到新的PCB中去,然后让两个进程同时运行。由于新的进程是从原来的进程所复制而来的,因此新进程会继承原来进程的所有资源和信息,包括内存、文件描述符、信号处理方式等。

需要注意的是,fork()函数并不保证父进程和子进程的执行顺序。在fork()之后,操作系统可能会先执行父进程,也可能会先执行子进程,这完全取决于系统的调度算法。

一般情况下,父进程和子进程之间是相互独立的,它们各自运行各自的代码,共享的只有一部分内存空间,而其他资源则是分别使用的。

#include<unistd.h>
#include<stdio.h>
int i=5;
int main() {if(fork()!=0)i++;elseprintf("%d\n",i);
}

此外,fork()函数还可以通过返回值来区分父进程和子进程,这使得父进程可以管理子进程的行为,例如等待子进程结束、获取子进程的状态等。

#include <stdio.h>
#include<unistd.h>
int main() {for(int i=0;i<3;i++){printf("%d\n",fork());}
}

需要注意的是,fork函数会返回两次,一次是在父进程中返回子进程的进程ID,一次是在子进程中返回0。

以下是七个fork例子

① Call once, return twice

void fork0() {if (fork() == 0) {printf("Hello from child\n");} else {printf("Hello from parent\n");}
}

创建一个子进程打印hello from child,父进程打印hello from parent

② Parent and child both run same code

void fork1() {int x = 1;pid_t pid = fork();if (pid == 0) {printf("Child has x = %d\n", ++x);} else {printf("Parent has x = %d\n", --x);}printf("Bye from process %d with x = %d\n", getpid(), x);
}

子进程会输出child has x=2和bye from process 子进程ID with x=2,父进程会输出parent has x=0和bye from process 父进程ID with x=0

③ Parent and child can continue forking

void fork2() {printf("L0\n");fork();printf("L1\n");fork();printf("Bye\n");
}

父进程输出一个L0、一个L1和一个Bye,一个子进程输出一个L1和一个Bye,一个子进程输出一个Bye,两个孙子进程输出两个Bye,一共一个L0、两个L1和四个Bye

④ Parent and child can continue forking

#define bork forkvoid borkfork() {bork();bork();bork();printf("borked\n");
}

父进程创建了一个子进程,然后二者又创建了两个子进程,然后四者又创建了四个子进程共八个进程输出八个borkfork

⑤ Parent and child can continue forking

void fork3() {printf("L0\n");fork();printf("L1\n");fork();printf("L2\n");fork();printf("Bye\n");
}

由③和④可知将会输出一个L0、两个L1、四个L2和八个Bye

⑥ Nested forks in parents

void fork4() {printf("L0\n");if (fork() != 0) {printf("L1\n");if (fork() != 0) {printf("L2\n");fork();}}printf("Bye\n");
}

由于只有在父进程中fork的返回值才会是进程ID,而子进程中fork的返回值永远是0,所以只有父进程会打印除L0、L1和L2并创建三个子进程,四个进程再打印出四个Bye

⑦ Nested forks in children

void fork5() {printf("L0\n");if (fork() == 0) {printf("L1\n");if (fork() == 0) {printf("L2\n");fork();}}printf("Bye\n");
}

父进程打印出L0,子进程打印出L1,子进程创建的子进程打印出L2并创建一个子进程,四个进程打印四个Bye

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 进阶篇】JDBC 数据库连接池详解

数据库连接池是数据库连接的管理和复用工具&#xff0c;它可以有效地降低数据库连接和断开连接的开销&#xff0c;提高了数据库访问的性能和效率。在 Java 中&#xff0c;JDBC 数据库连接池是一个常见的实现方式&#xff0c;本文将详细介绍 JDBC 数据库连接池的使用和原理。 1…

算法强训:第三十四天

文章目录 收件人列表养兔子一、收件人列表OJ链接 本题思路:先接收到一个数字,代表接下来是多少组数据 ,逐个接收每个名字,如果名字中没有,或者 则直接输出,否则在改名字前后拼接"\""再输出,除最后一个名字外,每个名字之后都有一个", " ,该组用例…

openstack-ansible部署zed版本all-in-one

目录 部署架构部署节点准备安装Rocky linux 9配置rocky 目标节点配置网络配置rocky linux网卡的创建永久网桥的方法&#xff1a; 部署前配置 部署架构 可用的操作系统&#xff1a; Debian11&#xff08;bullseye&#xff09; Ubuntu 22.04或20.04 CentOS Stream 9 或 Rocky Lin…

2023/8/8 下午10:42:04 objectarx

2023/8/8 下午10:42:04 objectarx 2023/8/8 下午10:42:16 ObjectARX(AutoCAD Runtime Extension)是用于开发和自定义AutoCAD软件的编程接口。ObjectARX允许开发者使用C++、.NET等编程语言来创建插件、扩展功能和定制化AutoCAD的行为。 通过ObjectARX,开发者可以访问Auto…

视频讲解|含可再生能源的热电联供型微网经济运行优化(含确定性和源荷随机两部分代码)

1 主要内容 该视频为《含可再生能源的热电联供型微网经济运行优化》代码讲解内容&#xff0c;对应的资源下载链接为考虑源荷不确定性的热电联供微网优化-王锐matlab&#xff08;含视频讲解&#xff09;&#xff0c;对该程序进行了详尽的讲解&#xff0c;基本做到句句分析和讲解…

国庆10.4

QT实现TCP服务器客户端 服务器 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket> //客户端头文件 #include <QList> //链表容器 #include <QMe…

【算法学习】-【双指针】-【快乐数】

LeetCode原题链接&#xff1a;202. 快乐数 下面是题目描述&#xff1a; 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 如果…

docker基础命令

目录 一、安装docker 1、查看是否已安装docker 2、如果系统中已经存在旧的Docker 3、配置Docker的yum库 4、安装成功后&#xff0c;执行命令&#xff0c;配置Docker的yum源 5、安装Docker 6、启动和校验 7、配置镜像加速器&#xff0c;阿里云镜像加速为例 7.1、在首页的…

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…

SpringCloudStreamkafka接收jsonarray字符串失败

文章目录 场景现象问题处理 场景现象 kafka作为消息队列&#xff0c;作为前端设备数据到后端消费的渠道&#xff0c;也被多个不同微服务消费一个服务与前端边缘计算设备建立socket消息&#xff0c;接收实时交通事件推送&#xff0c;再将事件发送到kafka里面。此处使用的是Spri…

window安装压缩版postgresql

环境&#xff1a; window 11 专业版postgresql-16.0-1-windows-x64-binaries.zip 一、下载 1.1 从官网下载 https://www.postgresql.org/download/windows/ 1.2 从百度网盘下载 链接&#xff1a;https://pan.baidu.com/s/1fmQbgWSzX4hN07Lgdzfz0g?pwddzyy 提取码&#…

C++ YAML使用

C++工程如何使用YAML-cpp 一、前期准备工作 1、已安装minGW、cmake、make等本地工具。 2、下载YAML-cpp第三方开源代码(一定要下载最新的release版本,不然坑很多)。 3、生成YAML-cpp静态库 (1)在yaml-cpp-master下建立build文件夹; (2)在该文件夹下生成MakaFile文…

C/C++字符函数和字符串函数详解————内存函数详解与模拟

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2 .memcpy函数 3.memmove函…

以太网基础学习(一)——以太网概述

一、以太网概述 以太网(Ethernet)指的是由 Xerox公司创建并由Xerox、Intel和 DEC公司联合开发的基带局域网规范&#xff0c;通用的以太网标准于1980年9月30日出台&#xff0c;是当今现有局域网采用的最通用的通信协议标准&#xff08;是局域网的一种&#xff09;。 以太网是一种…

数据结构与算法之堆: Leetcode 347. 前K个高频元素 (Typescript版)

前K个高频元素 https://leetcode.cn/problems/top-k-frequent-elements/ 描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2 输入: num…

【oncmdmsg 鼠标】2023/8/19 上午9:50:14

2023/8/19 上午9:50:14 oncmdmsg 鼠标 2023/8/19 上午9:50:22 抱歉,您提到的 “oncmdmsg” 和 “鼠标” 是什么?请提供更多上下文信息,我将尽力帮助您。 2023/8/19 上午9:51:43 OnCmdMsg 2023/8/19 上午9:52:21 “OnCmdMsg” 是一个在 MFC (Microsoft Foundation Cla…

(C++版)ROS2 bind函数解读

在ros2的发布者节点里面有这么一句话&#xff1a;估计没有学过C的人不太理解&#xff0c;这里我就发发好心帮忙解读一下timer_ this->create_wall_timer(500ms, std::bind(&MinimalPublisher::timer_callback, this)); timer_ this->create_wall_timer(500ms, std…

url请求头信息

Accept Accept&#xff1a;请求报头域&#xff0c;用于指定客户端可接受哪些类型的信息。 Accept-Language Accept-Language&#xff1a;指定客户端可接受的语言类型。 Accept-Encoding Accept-Encoding&#xff1a;指定客户端可接受的内容编码。 Host Host&#xff1a;…

自动驾驶中的感知模型:实现安全与智能驾驶的关键

自动驾驶中的感知模型&#xff1a;实现安全与智能驾驶的关键 文章目录 引言感知模型的作用感知模型的技术安全与挑战结论 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;全新的PnC培训…

unplugin-vue-components和unplugin-auto-import插件

unplugin-auto-import&#xff1a;自动按需引入 vue\vue-router\pinia 等的 api unplugin-vue-components&#xff1a;自动按需引入 第三方的组件库组件 和 我们自定义的组件 使用此类插件&#xff0c;不需要手动编写import {xxx} from vue这样的代码了&#xff0c;提升开发效…