linux环境高级编程之fork、getpid、getppid函数

【linuxC语言】进程概念与fork 在 Linux 系统编程中,进程是计算机中正在执行的程序的实例。每个进程都有自己独立的地址空间、代码段、数据段、堆栈等,使得它们能够彼此独立运行,互不干扰。Linux 系统中的进程是通过进程标识符(PID)来唯一标识的。而在 Linux 中,fork() 是一个非常重要的系统调用,用于创建新的进程。调用 fork() 后,将在原来的进程之上创建一个新的进程,新进程是原进程的一个副本,但具有自己独立的地址空间。本文将探讨进程的概念以及 fork() 函数的用法和作用。 阅读详情

前段时间学习了fork函数创建进程,在fork创建后用execl函数来执行linux下的命令。



fork函数()

一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

    一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。


用man fork 在linux下查看fork的用法

#include <unistd.h>

       pid_t fork(void);

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;
我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.





getpid用来获取当前进程ID

getppid用来获取当前进程的父进程的ID

用法:  
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
pid_t getppid(void);



我写了一段代码用来加深理解

[fanmaolin@Centeros duojincheng]$ vim testfork.c 

  1 /*********************************************************************************
  2  *      Copyright:  (C) 2017 fanmaolin<fanmaolinn@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  testfork.c
  6  *    Description:  This file 
  7  *                 
  8  *        Version:  1.0.0(05/09/2017)
  9  *         Author:  fanmaolin <fanmaolinn@gmail.com>
 10  *      ChangeLog:  1, Release initial version on "05/09/2017 07:28:18 PM"
 11  *                 
 testfork.c                                                                                                                         
 12  ********************************************************************************/
 13 
 14 #include <sys/types.h>
 15 #include <unistd.h>
 16 #include <stdio.h>
 17 int main ()
 18 {
 19     pid_t fpid=fork(); //fpid表示fork函数返回的值  
 20      int count=0;
 21 
 22     if (fpid < 0)
 23         printf("error in fork!");
 24     else if (fpid == 0)
 25     {
 26         printf("我是子进程\n");
 27         printf("i am the child process, my process id is %d\n",getpid());
 28         printf("My Parents's process id is %d\n",getppid());
 29         count++;
 30     }
 31     else
 32     {
 33         printf("我是父进程\n");
 34         printf("i am the parent process, my process id is %d\n",getpid());
 35         count++;
 36        sleep(1);//因为不确定父子进程谁会先执行,加个延时保证父进程先执行
 37     }
 38     printf("统计结果是: %d\n",count);
 39     return 0;
 40 }


执行结果




可以看到父进程ID为65869
子进程ID为65870
从子进程用getppid()获取父进程ID为65869
返回两次统计结果:1

父子进程间不确定谁会先执行。


问题总结:


关于为什么这里会返回两次1呢?

当父进程在执行的过程中,执行到sleep(1)时CPU分配给父进程的时间片到了,这时会执行子进程,执行完子进程后再来执行父进程,所以两个1是并列打印的,下面我们来看一下去掉sleep(1)的执行结果。

36 #ifdef SLEEP
 37        sleep(1);
 38 #endif

在这里有个技巧,因为有时我会用到sleep(1)有时又不会用到,加一个宏定义,如果我想用sleep时,
[fanmaolin@Centeros duojincheng]$ gcc testfork.c -o DSLEEP
[fanmaolin@Centeros duojincheng]$ ./a.out 
我是父进程
i am the parent process, my process id is 66512
我是子进程
i am the child process, my process id is 66513
My Parents's process id is 66512
统计结果是: 1
统计结果是: 1

如果我不想用sleep时

[fanmaolin@Centeros duojincheng]$ gcc testfork.c
[fanmaolin@Centeros duojincheng]$ ./a.out 
我是父进程
i am the parent process, my process id is 66527
统计结果是: 1
[fanmaolin@Centeros duojincheng]$ 我是子进程
i am the child process, my process id is 66528
My Parents's process id is 1
统计结果是: 1




看深红色字体,没有用sleep时的执行结果,会发现My Parents's process id is 1
子进程的父进程ID变成了“1”,这是为什么呢?
我们来看一下,哪一个进程的ID是1
[fanmaolin@Centeros duojincheng]$ ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1  19364  1264 ?        Ss   May08   0:03 /sbin/init

init进程的ID是1,原来我们不用sleep时,CPU如果先执行了父进程,父进程很快执行完了,子进程执行的时候没有了父进程,变成了孤儿进程,这个时候就被init进程收养了,所以子进程的父进程就变成了init进程。

在使用子进程的时候还要注意避免出现“僵尸进程”,所以要在父进程里给子进程“收尸”wait.

在分析类似问题时,一定要考虑到CPU时切片运行的,它留给每个程序的时间是有限的,差不多是ms级。
参考:
http://blog.youkuaiyun.com/jason314/article/details/5640969 fork
http://www.cnblogs.com/wannable/p/6021617.html  孤儿进程、僵尸进程、守护进程
S/4HANA Private Cloud 与 On-Premise 的 Key User Custom Fields 运输与升级避坑指南 本文探讨了SAP S/4HANA Cloud Private Edition和On-Premise系统中Key User Custom Fields的管理要点。文章指出,Custom Fields涉及元数据生成、对象一致性、传输治理等完整链路,操作不当会导致字段丢失或升级失败。关键建议包括:使用ATO Fiori App管理扩展项与传输绑定,配置正确的job user权限,避免在多系统并行开发同一字段。特别强调升级时需执行CFD_REGENERATE_IN_ONPREMISE报表,并通过标准传输机制推进变更 阅读详情

相关推荐

DSP28335做FFT傅里叶变换

1. 看了一下例程,居然没有FFT的例程,难道这个DSP28335不能做FFT吗?对了C2000系列是有C2000 ware这个库的。方便很多,不过目前不确定在C5000上运行的FFT能直接迁移到DSP28335上行不?测试了一下,是可以的,因为都是用的math.h,下面的一些正弦函数基本一样的 2. 硬件简介,其中DSP28335和TLV320AIC23B之间使用I2C接口进行寄存器配置,...

weixin_30390075的博客 3331

Linux系统调用之fork,getpid,getppid函数(进程相关函数,与G老师的对话,必看!)

如果,想要深入的学习Linux系统调用中的dup,dup2函数,还是需要去自己阅读Linux系统中的帮助文档。具体输入命令:即可查阅到完整的资料信息。

weixin_49503250的博客 4681

Unity AR涂涂乐实战:用户上传图片秒变3D模型新皮肤(附完整代码)

本文详细介绍了如何在Unity AR应用中实现用户上传图片动态生成3D模型皮肤的功能,重点讲解了动态创建材质球的技术方案和性能优化策略。通过完整的代码示例,开发者可以学习到多源图片处理、移动端内存管理以及AR场景适配等核心技巧,快速打造高性能的儿童教育类AR应用。

weixin_31509753的博客 370

linux getpid()和getppid()函数功能以及使用方法

getpid():获取当前进程ID ​ pid_t getpid(void); getppid 函数:获取当前进程的父进程 ID ​ pid_t getppid(void); #include <stdio.h> #include <stdlib.h> #include <unistd.h> int var = 100; //全局变量 int main(void) { pid_t pid; pid = fork(); // 创建一个子进程

weixin_43304992的博客 1万+

汽车ECU诊断入门:手把手教你用UDS协议(ISO14229)读取和清除故障码

本文详细介绍了如何使用UDS协议(ISO14229)进行汽车ECU诊断,包括故障码读取与清除的完整流程。从诊断环境搭建、UDS协议基础到实战案例分析,手把手教你掌握0x19诊断服务、安全访问机制等核心技能,适用于汽车电子工程师和诊断开发人员。

weixin_33701251的博客 454

免费测试国外大模型Claude 3.7 Sonnet API:无需api key(秘钥)

Claude 3.7 Sonnet是Anthropic公司推出的第三代Claude系列AI模型中的中规模版本(2024年发布),在性能与效率间实现平衡。该模型基于改进的Transformer架构,支持128K上下文窗口,擅长复杂推理、数学计算和创意写作,在GSM8K数学基准测试中准确率达92%。其采用"宪法AI"伦理框架,通过多轮对抗训练减少有害输出,同时新增多模态理解能力(可解析图片/图表内容)。Claude 3.7 Sonnet是Anthropic推出的高效轻量级大模型,主打快速响应与成本优化。

Explinks的博客 1498

进程:fork函数

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34061482的博客 182

Yolov8-pose关键点检测:loss优化 | LRM loss困难样本挖掘,提升难样本、遮挡物等检测精度

LRM loss应用到能够大幅提升pose遮挡物性能

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1716

fork、getpid、getppid函数

#include <unistd.h> pid_t fork(void); 作用:创建一个子进程。 到目前为止,我们可以直到两种创建进程的方法:1. 通过执行二进制文件来创建一个进程,如:./a.out /bin/ls;2.通过fork函数来创建一个子进程。 该函数没有形参,返回值类型为pid_t,为无符号整型。而进程的id为正整数。如果失败,则返回-1;如果成功,则由于父进...

luciusvorenus 3312

【人工智能】架构演进:基于本体论与 LLM Agent 的供应链备件决策闭环实践

本文探讨了如何将本体论(Ontology)与大语言模型(LLM)Agent结合,构建供应链备件管理的智能决策系统。针对LLM在垂直领域存在的幻觉和逻辑缺陷问题,提出通过本体论建立结构化知识框架,形成四层架构:知识建模、动态感知、深度分析和决策闭环。系统利用图数据库实例化领域本体,融合多源数据实现实时感知,结合图谱推理和时序预测进行确定性分析,最终通过工具调用完成决策执行。技术选型推荐Gemini 1.5 Pro、Neo4j和LangChain等工具,实现从自动化到智能化的升级。该架构为工业领域提供了可解释、

奶爸的编程之路,也就一周冷个三天 170

QNX侧触摸屏(TP)Bringup流程与源码深度解析

QNX侧TP Bringup的核心在于构建。

QQ_778132974的博客 477

linux_进程类相关学习-fork函数-getpid函数-getppid函数-getuid函数-geteuid函数-getgid函数-getegid函数-进程之间共享数据-进程gdb调试

fork函数 创建一个子进程 getpid函数 获取当前进程ID getppid函数 获取当前进程的父进程ID getuid函数 获取当前进程实际用户 geteuid函数 获取当前进程有效用户ID getgid函数 获取当前进程使用用户组ID getegid函数 获取当前进程有效用户组ID 进程之间共享数据-进程gdb调试 父子进程共享:1. 文件描述符(打开文件的结构体) 2. mmap建立的映射区 (后续再分享) gdb调试的时候 注意,区分一个函数是“系统函数”还是“库函数”依据: ①是否访问内核数

qq_44177918的博客 1157

Airtest进阶使用篇-提高脚本稳定性+批量运行脚本

Airtest进阶篇,主要分享如何提高脚本稳定性+如何批量运行脚本生成测试报告!

程序员小杨哥的博客 2569

Linux 进程 1.1 — fork 函数 创建进程,getpid() getppid()

pid_t fork(void); (pid_t 是一个宏定义,其实质是int 被定义在 #include<sys/types.h> 中) 复刻(英语:fork,又译作派生、分支)是UNIX或类UNIX中的分叉函数,fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。 fork 函数调用成功,返回两次,一次是父进程的 fork ,一次是子进程的 fork 返回值为 0

qq_45831156的博客 987

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

进程控制函数(fork、getpid、execl)

进程控制

qq_41864116的博客 1372

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【Linux系统编程】21.echo、env、fork、getpid、getppid

【Linux系统编程】21.echo、env、fork、getpid、getppid

因心,三人水的博客 422

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

linux环境下fork()函数简介

fork()函数原型:pid_t fork(void); 需要引入的头文件:<unistd.h> 功能: ①fork函数通过系统调用创建一个与原来进程几乎完全相同的进程,并且两个新的进程将并发执行。 ②若fork函数成功调用,一次会返回两个值,子进程返回0,父进程返回子进程ID(pid),若fork函数调用失败,返回-1 相关函数: (1)getpid 函数原型:pid_t getpid(void) 功能:返回当前进程的PID (2)getppid 函数原型:pid_t getppid(void

正在自我救赎的菜鸟。本人所有内容均不收费,可随意转发,复制 1728

Linux系统调用--getpid/getppid函数详解

【getpid/getppid系统调用】 功能描述: getpid返回当前进程标识,getppid返回父进程标识。 用法: #include <sys/types.h> #include <unistd.h> pid_t getpid(void); pid_t getppid(void); 注意的是需要在UNIX系统下使用头文件,VS不支持#include <sy...

苞米地里捉小鸡的博客 798

LINUX系统学习一(进程、MMU,环境变量、getenv、fork、getpid/getppid、ps、kill)

1、进程的概念 编译好的二进制文件叫程序 进行是运行起来的程序 站在程序员的角度:运行一系列指令的过程 站在操作系统角度:分配系统资源的基本单位 区别: 程序占用磁盘,不占用系统资源 进程占用系统资源 一个程序对应多个进程,可以同时运行多个,一个进程对应一个程序 程序没有生命周期,进程有生命周期 2、进程的过程 3、进程的状态 4、MMU的作用 1、虚拟内存和物理内存的映射 2、修改内存访问级别 3、用户空间映射到物理内在是独立的 5、进程控制块PCB root@

晨曦天下 342

进程控制 fork/getpid/getppid

进程控制 fork/getpid/getppid

weixin_43200943的博客 315

Linux—进程产生的方式(进程号、fork函数、system函数、exec函数、init进程)

目录 1. 进程号 1.1 getpid()、getppid()函数介绍 1.2 getpid()函数的例子 2. 进程复制fork() 2.1 fork()函数介绍 2.2 fork()函数的例子 3. system()方式 3.1 system()函数介绍 3.2 system()函数的例子 4. 进程执行exec()函数系列 4.1 exec()函数介绍 4.2 ex...

Change_Improve的博客 3007

子进程与父进程、getpid和getppid

#include <unistd.h> //unistd.h是unix std的意思,是POSIX标准定义的unix类系统定义符号常量的头文件 #include <sys/types.h> //是Unix/Linux系统的基本系统数据类型的头文件,含有size_t,time_t,pid_t等类型。 #include <sys/wait.h> //使...

Bily_on的博客 1788

父进程中getpid()值与子进程中getppid()值不相同的问题及解释

父进程中getpid()值与子进程中getppid()值不相同的问题及解释 使用fork()创建一个新的子进程,并调用getpid()与getppid()查看父子进程之间的pid的关系。示例代码如下: #include "common.h" int main() { pid_t pid; if ( (pid = fork()) < 0 ) { perror("fork()"); exit(1); } if ( pid ) { printf("parent process <

Goallegoal的博客 2781

Linux 2.进程(ps、top、fork、vfork、wait、waitpid、getpid、getppid)

进程什么是程序,什么是进程?程序进程如何查看系统中有哪些进程?1、使用 ps 指令查看2、使用top指令查看什么是进程标识符?什么是父进程,什么是子进程?C程序中的存储空间是如何分配的? 什么是程序,什么是进程? 程序 就是静态的一个概念。比如 gcc a.c -o a.out 那么这样就会在磁盘生成一个文件 a.out ,这个 a.out 就是一个程序。 进程 进程是我们程序的一次运行活动,当我们去运行这个 a.out 的时候,那么这个程序就跑起来了,此时系统中会多了一个进程。 如何查看系统中有哪些进程?

黄色的拉拉的博客 1921

Linux C/C++编程之(十六)进程及进程控制

文章目录一、概述 一、概述

种树最好的时间是10年前,其次是现在!!! 9969

Linux——fork函数原理、fork创建子进程、getpid和getppid、循环创建多个子进程⭐、父子进程共享⭐⭐、gdb调试父子进程

一、fork函数 fork()返回值是pid_t类型的 创建成功时子进程返回0,父进程返回子进程id,所以一次fork调用两次返回 二、创建子进程 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<pthread.h>...

qq_37299596的博客 955
上一篇: linux脚本使用-------安装madplay及MPlayer播放器脚本分析及命令参数前加“横杠”的背景解释
下一篇: 通过获取IP地址熟悉popen、str*系列、snprintf()、fgets
fml1997
博客等级 码龄10年 30粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值