fork函数详解

news2024/11/27 14:46:25

文章目录

  • fork函数
  • 例子详解
  • 工作原理
  • GDB 多进程调试

fork函数

fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。

通过man命令简单查看一下:man fork

在这里插入图片描述

基本概念

  • 每个进程都由进程号来标识,其类型为 pid_t(整型),进程号的范围:0~32767。进程号总是唯一的,但可以重用。当一个进程终止后,其进程号就可以再次使用。

  • 任何进程(除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。

  • 进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID)。默认情况下,当前的进程号会当做当前的进程组号

  • 进程号和进程组相关函数

    • pid_t getpid(void);:获取进程ID
    • pid_t getppid(void);:获取进程的父进程ID
    • pid_t getpgid(pid_t pid);:获取进程的组ID

fork()函数用法

pid_t fork(void);
    函数的作用:用于创建子进程。
    包含头文件:
    	#include <sys/types.h>
		#include <unistd.h>
    返回值:
        fork()的返回值会返回两次。一次是在父进程中,一次是在子进程中。
        在父进程中返回创建的子进程的ID,
        在子进程中返回0
        在父进程中返回-1,表示创建子进程失败,并且设置errno

例子详解

先来看一个最简单的例子

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() 
{

    // 创建子进程
    pid_t pid = fork();

    // 判断是父进程还是子进程
    if(pid > 0) {
        printf("pid : %d\n", pid);
        // 如果大于0,返回的是创建的子进程的进程号,当前是父进程
        printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());
    } else if(pid == 0) {
        // 当前是子进程
        printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());

    }
    for(int i = 0; i < 3; i++) {
        printf("i : %d , pid : %d\n", i , getpid());
        sleep(1);
    }
    return 0;
}

输出结果

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o test test.c  -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./test 
pid : 3274
i am parent process, pid : 3273, ppid : 2077
i : 0 , pid : 3273
i am child process, pid : 3274, ppid : 3273
i : 0 , pid : 3274
i : 1 , pid : 3273
i : 1 , pid : 3274
i : 2 , pid : 3273
i : 2 , pid : 3274

这个程序比较简单,唯一值得注意的是输出结果的这个语句i : 0 , pid : 3273

原因是fork之后父进程先执行还是子进程先执行不确定,取决于内核所使用的调度算法。

program

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

int main()
{
    int n=2;
    for(int i=0;i<n;i++)
    {
        fork();
        printf("A\n");
    }
    return 0;
}

输出结果

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o fork fork.c  -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./fork 
A
A
A
A
A
A

代码共打印6个A,创建3个子进程。
在这里插入图片描述
【注意】:‘\n’:会自动刷新缓冲区。即遇到\n会自动刷新缓冲区

program

我们把上面程序的\n删除掉在试一下。

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

int main()
{
    int n=2;
    for(int i=0;i<n;i++)
    {
        fork();
        printf("A");
    }
    return 0;
}

输出结果

(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o fork fork.c  -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./fork 
AAAA(base) user@ubuntu:~/Desktop/OS/NiuKe$ AAAA

代码共打印8个A。

在这里插入图片描述

工作原理

  • Linux 的 fork() 使用是通过写时拷贝 (copy- on-write) 实现。写时拷贝是一种可以推迟甚至避免拷贝数据的技术。
  • 内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间,只有在需要写入的时候才会复制地址空间,从而使各个进程拥有各自的地址空间。即资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享
  • fork之后父子进程共享文件。fork产生的子进程与父进程有相同的文件描述符,指向相同的文件表,引用计数增加,共享文件偏移指针。

GDB 多进程调试

  • 使用 GDB 调试的时候,GDB 默认只能跟踪一个进程,可以在 fork 函数调用之前,通过指令设置 GDB 调试工具跟踪父进程或者是跟踪子进程,默认跟踪父进程

  • 设置调试父进程或者子进程:set follow-fork-mode [parent(默认)| child]

  • 设置调试模式:set detach-on-fork [on | off]
    默认为 on,表示调试当前进程的时候,其它的进程继续运行,如果为 off,调试当前进程的时候,其它进程被 GDB 挂起。

  • 查看调试的进程:info inferiors

  • 切换当前调试的进程:inferior Num

  • 使进程脱离 GDB 调试:detach inferiors Num

参考资料:89-多进程开发:GDB多进程调试

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

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

相关文章

jvm系列(2)--类加载子系统

目录第2章-类加载子系统内存结构概述简图详细图类加载器子系统类加载器ClassLoader角色类加载过程概述加载阶段链接阶段验证(Verify)准备(Prepare)解析(Resolve)初始化阶段类的初始化时机clinit()1&#xff0c;2&#xff0c;3说明4说明5说明6说明类加载器的分类概述虚拟机自带的…

【web安全】——文件上传的绕过方式

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右铭…

价值创造链路及经营计划

“价值创造过程最主要的环节是建立链接&#xff0c;北京万柳书院在网上热议&#xff0c;其背后是人与人的大量链接&#xff0c;近期热议的湖南卫视春晚亦如是&#xff0c;这种链接为价值的设计、沟通、传递创造条件&#xff1b;企业以客户为中心设计产品&#xff0c;往大了说是…

C++ string类的初步了解

目录 一. 为什么学习string类&#xff1f; 1.C语言中的字符串 2.string类 二. string类的常用接口说明 1.构造 2.容量 size和length capacity clear empty reserve resize 3.元素访问 operator[] at front、back 4.迭代器 ​编辑begin、end rbegin、rend …

数据结构初阶:排序

本期博客我们来到了初阶数据结构最后一个知识点&#xff1a;排序 排序&#xff0c;我们从小到大就一直在接触&#xff0c;按身高、成绩、学号等等不同的排序我们已经历许多&#xff0c;那么各位是按怎样的方法进行排序的呢&#xff1f; 废话不多说这期博客我们对各种排序方法…

测试开发 | 测试平台开发-前端开发之数据展示与分析

本文节选自霍格沃兹测试学院内部教材测试平台的数据展示与分析&#xff0c;我们主要使用开源工具ECharts来进行数据的展示与分析。ECharts简介与安装ECharts是一款基于JavaScript的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化…

Unity 使用OpenXR和XR Interaction Toolkit 开发 HTCVive(Vive Cosmos)

Unity 使用OpenXR和XR Interaction Toolkit 开发 HTCVive&#xff08;Vive Cosmos&#xff09; 提示&#xff1a;作者是 Unity 2020.3 以上版本做的开发。开发VR程序需要安装 Steam&#xff0c;SteamVR, (Vive Cosmos,需要再安装VIVEPORT,VIVEConsole) OpenXR 控制设备 &#x…

OpenCV(12)-OpenCV的机器学习

OpenCV的机器学习 基本概念 计算机视觉是机器学习的一种应用&#xff0c;而且是最有价的应用 人脸识别 哈尔(Haar)级联方法深度学习方法(DNN) Haar人脸识别方法 哈尔(Haar)级联方法是专门为解决人脸识别而推出的&#xff0c;在深度学习还不流行时&#xff0c;哈尔已可以商…

Android 深入系统完全讲解(21)

关键性 EGLSurface 代码位置 继续再看看&#xff0c;代码跑到 C 里面去了。 然后关键点&#xff1a; 获取本地窗口&#xff0c;创建 Surface&#xff0c;然后 toEGLHandle 进行包裹&#xff0c;变成 EGL 上下文。 EGLSurface 。 绘制的设计本质逻辑 在这里就回归一点&#xff…

Unity学习笔记--File.ReadAllLines和File.ReadAllText的使用以及注意事项(一定要看到最后!!!)

目录前言一、File.ReadAllLines参数返回例子二、File.ReadAllText参数返回例子注意事项可能出现的问题总结前言 最近在做文件存储以及读取的时候&#xff0c;需要用到C#给我们提供的类&#xff1a;File 具体使用方法可以看官方文档&#xff1a;C# File 类 这篇文章只会说File.…

深度学习基础理念(一)

文章目录1. 机器学习 Machine Learing机器学习类别2. 机器如何找函数深度学习输入类型和输出类型机器如何找函数的1. 机器学习 Machine Learing 什么是机器学习&#xff0c;顾名思义 机器 拥有会学习的能力&#xff0c;机器学习就是让机器具备能够找函数的能力 机器学习就是找…

【C语言课程设计】通讯录(1.0版本)

前言 相信各位对于通讯录都不是很陌生吧。通讯录我们在学校的大作业&#xff0c;课程设计经常会去使用它。那么今天我们将使用C语言来实现一个简单的通讯录。 目录 前言 一、通讯录的需求 二、工程文件的创建 三、通讯录的声明和定义 四、通讯录各函数的声明和定义 五、通…

Mysql入门技能树-数据查询-练习篇

SELECT 下列 SQL 语句&#xff0c;哪一项不合法&#xff1f; 答案是&#xff1a;C select now(),3.14 now() |3.14| ----------------------- 2023-01-16 16:47:04|3.14|MySQL查询表中所有的数据可以通过“SELECT * 通配符”或者“SELECT 所有字段”实现。 SE…

hadoop3.x源码编译及cmake的问题解决:CMake failed with error code 1

一、准备工作 基础环境&#xff1a;centos7 &#xff08;1&#xff09;官方源码中编译之前对基础环境及版本的要求&#xff08;重点是红色部分&#xff09; Requirements: * Unix System* JDK 1.8 * Maven 3.3 or later * ProtocolBuffer 2.5.0 * CMake 3.1 or newer (if com…

OSCP-Vulnhub靶机记录-Hacker_Kid-v1.0.1

Vulnhub靶机记录-Hacker_Kid-v1.0.1介绍&安装信息收集页面源代码DIG信息收集xxe漏洞探测9999端口SSTI模板注入发现具有Capabilities特殊操作权限的程序原理介绍&安装 靶机名称&#xff1a;Hacker_Kid-v1.0.1 靶机难度&#xff1a;中等 虚拟机环境&#xff1a;此靶机推…

【Linux】线程互斥

目录&#x1f308;前言&#x1f338;1、Linux线程互斥&#x1f367;1.1、线程间互斥相关背景概念&#x1f368;1.2、互斥量(锁)相关背景&#x1f36f;1.3、互斥量(锁)相关API&#x1f36f;1.3.1、初始化和销毁互斥锁&#x1f370;1.3.2、互斥量加锁和解锁&#x1f372;1.3.3、互…

Python爬虫403错误的解决方案

前言程序使用一段时间后会遇到HTTP Error 403: Forbidden错误。 因为在短时间内直接使用Get获取大量数据&#xff0c;会被服务器认为在对它进行攻击&#xff0c;所以拒绝我们的请求&#xff0c;自动把电脑IP封了。 解决这个问题有两种方法。一是将请求加以包装&#xff0c;变成…

1.浮动float

提示&#xff1a;如果多一个盒子&#xff08;都设置浮动&#xff0c;则它们会按照属性值一行内显示并且顶端对齐排列&#xff09; 注意&#xff1a; 浮动的元素是互相贴靠在一起的&#xff0c;&#xff08;没有缝隙&#xff09;&#xff0c;如果父级宽度装下这些浮动盒子&#…

MyBatis 详解 (2) -- 增删改操作

MyBatis 详解 2 -- 增删改操作前言一、准备工作1.1 创建数据库和表1.2 添加实体类1.3 添加 mapper 接口 (数据持久层)1.4 创建与接口对应的 xml 文件二、增加操作2.1 默认返回受影响的行数2.2 特殊的新增&#xff1a;返回自增 id三、删除操作四、修改操作五、实现完整交互5.1 添…

爆肝9万字,我已从小白晋升ARM嵌入式工程师!带你从零熟悉常用的M4嵌入式功能,建议收藏(含码源)

&#x1f4da; 前言 &#x1f4d1;博客主页&#xff1a;丘比特惩罚陆 &#x1f496;欢迎关注&#xff1a;点赞收藏⭐留言✒ &#x1f4ac;系列专栏&#xff1a;web前端、嵌入式、笔记专栏 &#x1f3ae; 加入社区&#xff1a; 丘比特惩罚陆 &#x1f947;人生格言&#xff1a;选…