【Linux操作系统】深入探索Linux进程:创建、共享与管理

进程的创建是Linux系统编程中的重要概念之一。在本节中,我们将介绍进程的创建、获取进程ID和父进程ID、进程共享、exec函数族、wait和waitpid等相关内容。
在这里插入图片描述

文章目录

    • 1. 进程的创建
      • 1.1 函数原型和返回值
      • 1.2 函数示例
    • 2. 获取进程ID和父进程ID
      • 2.1 函数原型和返回值
      • 2.2 函数示例
    • 3. exec函数族
      • 3.1 `exec()`函数族的常见成员:
      • 3.2 函数示例
    • 4. wait和waitpid
      • 4.1 函数解释
      • 4.2 函数示例
  • 总结


1. 进程的创建

在Linux系统中,进程的创建使用fork()系统调用。fork()系统调用会创建一个与当前进程相同的子进程,子进程会复制父进程的所有资源,包括代码、数据和文件描述符等。


1.1 函数原型和返回值

fork()函数的原型如下:

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

fork()函数 没有任何参数 ,它的返回值是一个pid_t类型的整数。具体解释如下:

  • 如果调用成功,fork()函数会在父进程中返回子进程的PID(子进程ID),在子进程中返回0。
  • 如果调用失败,fork()函数会返回-1,并设置errno来指示错误类型。

1.2 函数示例

代码示例如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid == -1) {printf("Failed to fork a new process.\n");return 1;} else if (pid == 0) {printf("This is the child process.\n");} else {printf("This is the parent process.\n");}return 0;
}

上述代码中,fork()系统调用会返回两次,分别在父进程和子进程中返回。通过判断返回值,我们可以区分父进程和子进程,并执行不同的代码逻辑。



2. 获取进程ID和父进程ID

在Linux系统中,可以使用getpid()getppid()系统调用来获取当前进程的ID和父进程的ID。


2.1 函数原型和返回值

getpid()getppid()函数的原型如下:

#include <sys/types.h>
#include <unistd.h>pid_t getpid(void);
pid_t getppid(void);

这两个函数都 没有任何参数 ,它们的返回值都是一个pid_t类型的整数。具体解释如下:

  • getpid()函数返回调用进程的进程ID(PID)。
  • getppid()函数返回调用进程的父进程的进程ID(PPID)。

2.2 函数示例

代码示例如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main() {pid_t pid = getpid();pid_t ppid = getppid();printf("Process ID: %d\n", pid);printf("Parent Process ID: %d\n", ppid);return 0;
}


3. exec函数族

在Linux系统中,exec()函数族可以用于将当前进程替换为新的程序。exec()函数族包括execl()execv()execle()execve()等函数。这些函数可以根据不同的参数形式来执行不同的替换方式。


3.1 exec()函数族的常见成员:

  1. int execl(const char *path, const char *arg, ...);

    • 参数 path 是要执行的新程序的路径。
    • 参数 arg 是一个字符串,表示新程序的第一个参数。
    • 可变参数列表是新程序的其他参数,必须以 NULL 结束。
    • 函数执行成功时不会返回,如果返回则表示执行失败。

  2. int execv(const char *path, char *const argv[]);

    • 参数 path 是要执行的新程序的路径。
    • 参数 argv 是一个字符串数组,表示新程序的参数列表,最后一个元素必须是 NULL
    • 函数执行成功时不会返回,如果返回则表示执行失败。

  3. int execle(const char *path, const char *arg, ..., char *const envp[]);

    • 参数 path 是要执行的新程序的路径。
    • 参数 arg 是一个字符串,表示新程序的第一个参数。
    • 可变参数列表是新程序的其他参数,必须以 NULL 结束。
    • 参数 envp 是一个字符串数组,表示新程序的环境变量列表,最后一个元素必须是 NULL
    • 函数执行成功时不会返回,如果返回则表示执行失败。

  4. int execvp(const char *file, char *const argv[]);

    • 参数 file 是要执行的新程序的文件名。
    • 参数 argv 是一个字符串数组,表示新程序的参数列表,最后一个元素必须是 NULL
    • 函数执行成功时不会返回,如果返回则表示执行失败。

这些函数在执行成功时不会返回,而是直接将当前进程替换为新程序。如果返回,则表示执行失败,可以根据返回值来判断错误类型。

exec()函数族可以用于在当前进程中加载和执行新程序,可以实现程序的动态切换和功能扩展。一般情况下,exec()函数族会在调用fork()函数创建子进程后使用,以替换子进程的代码和数据。


3.2 函数示例

代码示例如下:

#include <stdio.h>
#include <unistd.h>int main() {printf("Before exec()\n");execl("/bin/ls", "ls", "-l", NULL);printf("After exec()\n");return 0;
}

上述代码中,execl()函数会将当前进程替换为ls -l命令。execl()函数的第一个参数是要执行的程序路径,后续参数是传递给新程序的命令行参数。



4. wait和waitpid

在Linux系统中,父进程可以使用wait()waitpid()系统调用等待子进程的结束。这些系统调用会阻塞父进程的执行,直到子进程结束。


4.1 函数解释

wait()waitpid()是用于等待子进程结束并获取子进程的退出状态的函数。

  1. pid_t wait(int *status);

    • 函数会挂起当前进程,直到一个子进程结束。
    • 如果成功等到子进程结束,函数会返回子进程的进程ID。
    • 参数 status 是一个指向整型的指针,用于存储子进程的退出状态信息。
    • 如果调用失败,函数会返回-1。

  2. pid_t waitpid(pid_t pid, int *status, int options);

    • 函数会挂起当前进程,直到指定的子进程结束。
    • 参数 pid 指定要等待的子进程的进程ID。
    • 参数 status 是一个指向整型的指针,用于存储子进程的退出状态信息。
    • 参数 options 是一个整型值,用于指定等待的选项。
    • 如果调用失败,函数会返回-1。

wait()waitpid()函数的返回值是子进程的进程ID,如果调用失败,则返回-1。通过参数 status 可以获取子进程的退出状态信息,包括退出码、终止信号等。

waitpid()函数相比于wait()函数更加灵活,可以通过参数 pidoptions 控制等待的子进程。

其中,pid 的取值可以是:

  • -1:等待任意子进程。
  • 0:等待与当前进程组ID相同的子进程。
  • 具体的子进程ID:等待指定的子进程。

options 参数可以通过位掩码的方式指定多个选项,常用的选项有:

  • WNOHANG:非阻塞方式,如果没有子进程结束,立即返回。
  • WUNTRACED:也会返回已经停止的子进程的状态。
  • WCONTINUED:也会返回已经继续运行的子进程的状态。

wait()waitpid()函数可以用于处理子进程的退出状态,释放子进程的资源,并进行进程间的同步。在使用这两个函数时,需要注意处理错误情况和避免僵尸进程的产生。


4.2 函数示例

代码示例如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid == -1) {printf("Failed to fork a new process.\n");return 1;} else if (pid == 0) {printf("This is the child process.\n");} else {wait(NULL);printf("This is the parent process.\n");}return 0;
}

上述代码中,父进程使用wait(NULL)系统调用等待子进程的结束。wait()系统调用会阻塞父进程的执行,直到子进程结束。



总结

  1. fork()函数:用于创建子进程,返回值不同表示在不同的进程中执行。
  2. exec()函数族:用于在当前进程中加载和执行新程序,可以实现程序的动态切换和功能扩展。
    • execl():接受可变参数的形式,参数以字符串形式传递。
    • execle():接受可变参数的形式,同时传递环境变量。
    • execvp():接受参数数组的形式,参数以字符串数组形式传递。
  3. wait()waitpid()函数:用于等待子进程结束并获取子进程的退出状态。
    • wait():等待任意子进程结束。
    • waitpid():可以指定等待的子进程。
    • 通过参数 status 可以获取子进程的退出状态信息。
    • 可以通过 options 参数控制等待的选项,如非阻塞方式等。
    • 需要注意处理错误情况和避免僵尸进程的产生。

这些函数和系统调用可以用于进程的创建、执行和等待,实现进程间的同步和协作。通过这些函数,可以实现进程的动态切换、功能扩展和资源释放。同时,需要注意处理错误情况,避免产生僵尸进程和资源泄漏的问题。

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

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

相关文章

接口测试及接口抓包常用测试工具和方法?

作为测试领域中不可或缺的一环&#xff0c;接口测试和抓包技术在软件开发过程中扮演着至关重要的角色。不论你是新手还是有一些经验的小伙伴&#xff0c;本篇文章都会为你详细介绍接口测试的基本概念、常用测试工具和实际操作技巧&#xff0c;让你轻松掌握这一技能。 接口测试…

Java数字化智慧工地管理云平台源码(人工智能、物联网、大数据)

智慧工地优势&#xff1a;"智慧工地”将施工企业现场视频管理、建筑起重机械安全监控、现场从业人员管理、物料管理、进度管理、扬尘噪声监测等现场设备有机、高效、科学、规范的结合起来真正实现工程项目业务流与现场各类监控源数据流的有效结合与深度配合&#xff0c;实…

【JVM】对String::intern()方法深入详解(JDK7及以上)

文章目录 1、什么是intern&#xff1f;2、经典例题解释例1例2例3 1、什么是intern&#xff1f; String::intern()是一个本地方法&#xff0c;它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串&#xff0c;则返回代表池中这个字符串的String对象的引用&#…

Java开源项目mall学习笔记(1)——项目初始化

一、学习声明与项目介绍 该笔记是记录学习开源项目mall过程的文档笔记&#xff0c;完全原创&#xff0c;转载请声明。同时也对开源项目的作者表示感谢&#xff01; mall: &#x1f525; mall项目是一套基于 SpringBoot Vue uni-app 实现的电商系统&#xff0c;包括前台商城项…

ArcGIS 利用cartogram插件制作变形地图

成果图 注&#xff1a;本图数据并不完全对&#xff0c;只做为测试用例 操作 首先需要下载一个插件cartogram 下载地址在这里 https://www.arcgis.com/home/item.html?idd348614c97264ae19b0311019a5f2276 下载完毕之后解压将Cartograms\HelpFiles下的所有文件复制到ArcGIS…

【Git】(二)分支

1、创建分支 已存在主分支master&#xff0c;现在需要创建v1.0的版本&#xff0c;一般直接在web页面操作。 v1.0分支&#xff0c;基线master&#xff0c;称为项目分支。 假如&#xff0c;v1.0项目存在两个项目成员sunriver2000和snow&#xff0c;一般还会再针对个人创建个人…

nodejs+vue+elementui学生档案信息管理系统_06bg9

利用计算机网络的便利&#xff0c;开发一套基于nodejs的大学生信息管理系统&#xff0c;将会给人们的生活带来更多的便利&#xff0c;而且在经济效益上&#xff0c;也会有很大的便利!这可以节省大量的时间和金钱。学生信息管理系统是学校不可缺少的一个环节&#xff0c;其内容直…

说一下什么是tcp的2MSL,为什么客户端在 TIME-WAIT 状态必须等待 2MSL 的时间?

1.TCP之2MSL 1.1 MSL MSL:Maximum Segment Lifetime报文段最大生存时间&#xff0c;它是任何报文段被丢弃前在网络内的最长时间 1.2为什么存在MSL TCP报文段以IP数据报在网络内传输&#xff0c;而IP数据报则有限制其生存时间的TTL字段&#xff0c;并且TTL的限制是基于跳数 1.3…

[高光谱]PyTorch使用CNN对高光谱图像进行分类

项目原地址&#xff1a; Hyperspectral-Classificationhttps://github.com/eecn/Hyperspectral-ClassificationDataLoader讲解&#xff1a; [高光谱]使用PyTorch的dataloader加载高光谱数据https://blog.csdn.net/weixin_37878740/article/details/130929358 一、模型加载 在…

使用JMeter创建数据库测试

好吧&#xff01;我一直觉得我不聪明&#xff0c;所以&#xff0c;我用最详细&#xff0c;最明了的方式来书写这个文章。我相信&#xff0c;我能明白的&#xff0c;你们一定能明白。 我的环境&#xff1a;MySQL&#xff1a;mysql-essential-5.1.51-win32 jdbc驱动&#xff1a;…

mysql 03.查询(重点)

先准备测试数据&#xff0c;代码如下&#xff1a; -- 创建数据库 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 创建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入数据…

PHP 公交公司充电桩管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 公交公司充电桩管理系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 源码下载 https://download.csdn.net/download/qq_41221322/88220946 论文下…

苹果手机批量删除联系人的2个方法,请查收!

【想要清理通讯录里的“僵尸号”&#xff0c;但是突然发现手机不能批量删除。一个一个删除太麻烦了&#xff0c;有什么办法可以一次性多删几个人吗&#xff1f;】 小编想问问果粉们平时都是怎么删除联系人的&#xff1f;特别是要删除多个联系人的时候&#xff0c;大家还是选择…

matlab保存图片

仅作为记录&#xff0c;大佬请跳过。 文章目录 用界面中的“另存为”用saveas 用界面中的“另存为” 即可。 参考 感谢大佬博主文章&#xff1a;传送门 用saveas 必须在编辑器中的plot之后用saveas&#xff08;也就是不能在命令行中单独使用——比如在编辑器中plot&#xf…

基于平台的城市排水泵站管理系统设计

安科瑞 耿敏花 近年来我国城市内涝灾害频发&#xff0c;造成人员伤亡以及经济损失严重&#xff0c;严重威胁着城市的安全。数据显示&#xff0c;2015-2018年我国平均每年受淹或发生内涝城市的数量约占我国城市数量的1/5&#xff1b;人民生命财产也损失严重&#xff0c;据统计&a…

基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】

这里主要是前一篇博文的后续内容&#xff0c;简单回顾一下&#xff1a;本文选取了n/s/m三款不同量级的模型来依次构建训练模型&#xff0c;所有的参数保持同样的设置&#xff0c;之后探索在不同剪枝处理操作下的性能影响。 在上一篇博文中保持30的剪枝程度得到的效果还是比较理…

C++ 学习系列3 -- 函数压栈与出栈

在C中&#xff0c;函数压栈&#xff08;函数调用&#xff09;和出栈&#xff08;函数返回&#xff09;是函数调用过程中的两个关键步骤。下面将逐步解释这两个过程&#xff1a; 一 函数压栈与出栈过程简介 函数压栈&#xff08;函数调用&#xff09;的过程如下&#xff1a; …

2020年3月全国计算机等级考试真题(C语言二级)

2020年3月全国计算机等级考试真题&#xff08;C语言二级&#xff09; 第1题 有以下程序 void fun1 (char*p) { char*q; qp; while(*q!\0) { (*Q); q&#xff1b; } } main() { char a[]{"Program"},*p; p&a[3]; fun1(p); print…

新能源电动车充电桩控制主板安全特点

新能源电动车充电桩控制主板安全特点 你是否曾经担心过充电桩的安全问题?充电桩主板又是什么样的呢?今天我们就来聊聊这个话题。 充电桩主板采用双重安全防护系统&#xff0c;包括防水、防护、防尘等&#xff0c;确保充电桩安全、可靠。不仅如此&#xff0c;充电桩主板采用先…

简单的洗牌算法

目录 前言 问题 代码展现及分析 poker类 game类 Text类 前言 洗牌算法为ArrayList具体使用的典例&#xff0c;可以很好的让我们快速熟系ArrayList的用法。如果你对ArrayList还不太了解除&#xff0c;推荐先看本博主的ArrayList的详解。 ArrayList的详解_WHabcwu的博客-CSD…