进程的重要函数

进程的重要函数:

fork函数

了解fork函数

通过调用fork()函数,则会产生一个新的进程。调用fork()函数的进程叫做 父进程,产生的新进程则为子进程。
其编码过程:
1.函数功能:

函数头文件
#include <sys/types.h>
#include <unistd.h>
函数原型
pid_t fork(void);
函数功能
创建一个子进程
函数返回值
成功:返回给父进程是子进程的pid,返回给子进程的是0
失败:返回-1,并设置errno

2.代码实例:

// 创建一个子进程,并打印 Hello fork
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid==-1){perror("fork");return -1;}printf("Hello fork.\n");return 0;
}

fork创造的父子进程的特点

通过 fork() 函数创建子进程,有如下特点:

  • 父子进程并发执行,子进程从 fork() 函数之后开始执行
    在这里插入图片描述
  • 父子进程的执行顺序由操作系统算法决定的,不是由程序本身决定
  • 子进程会拷贝父进程地址空间的内容,包括缓冲区、文件描述符等
    代码示例:
// 父子进程数据空间拷贝,缓冲区的拷贝
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{// 标准IOwrite(1,"write hello.",12);// 文件IO自带缓冲区fputs("fputs hello.",stdout); // 注意没有换行符,stdout的缓冲区属于行缓冲pid_t pid = fork();if(pid==-1){perror("fork");return -1;}printf("pid = %d,Hello fork.\n",getpid());return 0;
}

运行结果:

1.write hello.fputs hello.pid = 4711,Hello fork.
2.fputs hello.pid = 4712,Hello fork.

创建多个进程

在创建多个进程时,最主要的原则是由父进程统一创建,统一管理,不能进行递归创建
在这里插入图片描述
代码公示列:

#include <sys/types.h>
#include <unistd.h>
#include<stdio.h>
#include <stdlib.h>
//一定要创建子进程一定要在父进程中进行
int main(){printf("hellow process\n");pid_t pid1 = fork();//先创建第一个子进程if(pid1 == 0)//如果创建返回为0,则为子进程,如果大于0,则为为父进程{printf("son1 start\n");printf("son2 end\n");}else if(pid1 == -1){perror("创建失败");exit(EXIT_FAILURE);}else if(pid1 > 0){pid_t pid2 = fork();//创建第二个子进程if(pid2 == 0){printf("son2 start\n");printf("son2 end\n");}else if(pid2 == -1){perror("创建失败");exit(EXIT_FAILURE);}else{printf("parent start\n");printf("parent end\n");}}
}

题目结果:

请添加图片描述

wait函数和waitpid函数

wait函数:

函数功能及引用头文件:

1.函数头文件
#include <sys/types.h>
#include <sys/wait.h>2.函数原型
pid_t wait(int *wstatus);3.函数功能
让函数调用者进程进入到睡眠状态,等待子进程进入僵死状态后,释放相关资源并返回4.函数参数
wstatus:保存子进程退出状态值变量的指针
*****获取具体值需要使用宏定义*****5.函数返回值
wait(): on success, returns the process ID of the terminated child; on error,
-1 is returned.
成功:返回退出子进程的pid
失败:返回-1

2.函数代码示例(以下拿c++代码来实现):

using namespace std;
#include <iostream>
#include <string> 
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(){pid_t pid = fork();if(pid == -1){cout << "创建失败"  << endl;exit(EXIT_FAILURE);}else if(pid == 0){cout << "son start" << endl;sleep(2);cout << "son end" << endl; exit(1000);}else if(pid > 0){int wat = 0;wait(&wat);} return 0;
}

运行结果:
请添加图片描述
由此可得等待功能是多么强大,它能让父进程休眠,等子进程完成后,父进程才开始,但waitpid更强大

waitpid函数

函数功能及引用头文件:
waitpid函数的功能与wait函数一样,但比wait()函数功能更强大,可以理解成 wait() 底层调用waitpid()函数

1.函数头文件
#include <sys/types.h>
#include <sys/wait.h>
2.函数原型
pid_t waitpid(pid_t pid, int *wstatus, int options);
3.函数参数
pid:进程id
-1 可以等待任意子进程
>0 等待id为pid的进程
wstatus:保存子进程退出状态值的指针
options:选项
WNOHANG 非阻塞选项
0 阻塞式与wait等同
4.函数返回值
成功
>0 退出进程的pid
=0 在非阻塞模式下,没有进程退出
失败
-1,并设置errno

函数代码:

using namespace std;
#include <iostream>
#include <string> 
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(){pid_t pid = fork();if(pid == -1){cout << "创建失败"  << endl;exit(EXIT_FAILURE);}else if(pid == 0){cout << "son start" << endl;sleep(3);cout << "son end" << endl; exit(1000);}else if(pid > 0){pid_t pid1 = fork();if(pid1 == 0){cout << "son1 start" << endl;sleep(3);cout << "son2 end" << endl;exit(50);}else if(pid1 == -1){cout << "创建pid1失败" << endl;}else if(pid1 > 0){int cpid = 0;//waitpid(-1,NULL,0);//这是waitpid用的最多的形式while((pid = waitpid(-1,NULL,0)) != -1);//此方式可以阻挡多线程	cout << "parent start" << endl;cout << "parent end" << endl;  }} return 0;
}

重点! 重点! 重点!:

int cpid = 0;while((cpid=waitpid(-1,&status,WNOHANG))==0);//这种方式可以阻绝任意进程是必须要掌握等待函数

与进程替换有关的函数(重点)

应用场景:

  • Linux 终端应用程序,在执行命令时,通过创建一个进程,然后替换成对应命令的可执行程序,在执行。

在这里插入图片描述
exec函数族(重点) :

int execl(const char *pathname, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, .../* (char *) NULL */);
int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char 
*const envp[] */);
int execv(const char *pathname, char *const argv[]);//最简单,最方便 
int execvp(const char *file, char *const argv[]);//最简单,最方便 
int execvpe(const char *file, char *const argv[],char *const envp[]);

参数说明:

path:可执行文件的路径名
file:可执行文件名,可以通过PATH环境变量指定的路径
arg:参数列表,以NULL结尾
argv[]:参数数组
envp[]:环境变量数组

返回值:

The exec() functions return only if an error has occurred. The return value
is -1, and errno is set to indicate the error.

其中一个示例代码(c语言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define SIZE 10
int main(){char* param[SIZE];char command[128] = { 0 };int pipefd[2];int ret = pipe(pipefd);if(ret == -1){perror("pipe");exit(EXIT_FAILURE);}pid_t pid = fork();if(pid == -1){perror("pid");exit(EXIT_FAILURE);}else if(pid == 0){close(pipefd[1]);char buf[128] = { 0 };size_t rtype = read(pipefd[0],buf,sizeof(buf));printf("read buf:%s\n",buf);if(rtype == 0){printf("1\n");close(pipefd[0]);exit(EXIT_SUCCESS);}else if(rtype == -1){perror("rtype");close(pipefd[0]);exit(EXIT_FAILURE);}int index = 0;//用strtok函数将命令分割开装入数组中,以便进行进程替换char* cmd_name = strtok(buf," ");param[index] = cmd_name;index++;char* ret = NULL;while((ret = strtok(NULL," ")) != NULL){param[index] =  ret;index++; }param[index] = NULL;int ret_value = execvp(cmd_name,param);//这是exec族的一个函数用来进行进行替换if(ret_value == -1){perror("ret_value");exit(EXIT_FAILURE);}close(pipefd[0]);}else{close(pipefd[0]);memset(command,0,sizeof(command));printf("请输入你要实现的命令:\n");fgets(command,sizeof(command),stdin);command[strlen(command) - 1] = '\0';if(strcmp(command,"quit") == 0){printf("master\n");exit(EXIT_SUCCESS);}printf("command=%s\n",command);size_t wtype = write(pipefd[1],command,strlen(command));printf("wtype=%ld\n",wtype);if(wtype == -1){perror("wtype");close(pipefd[1]);exit(EXIT_FAILURE);}sleep(1);close(pipefd[1]);waitpid(-1,NULL,0);}}

请添加图片描述
所以exec族的函数可以进行进程替换,让系统响应:
在这里插入图片描述

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

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

相关文章

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—你的透明背景图片生成工具

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可…

C++ STL全面解析:六大核心组件之一----迭代器(STL进阶学习)

目录 迭代器&#xff08;iterator&#xff09; 迭代器的分类 迭代器的使用 创建迭代器 迭代器的基本操作 使用迭代器遍历容器 迭代器的有效性和安全性 迭代器的类型 迭代器与算法 迭代器设计思维 迭代器的本质 文件 mylist-iter.h 文件 mylist-iter-test.cpp 迭代…

多线程学习篇三:共享带来的问题及解决方案

1. 共享带来的问题 1.1 案例演示 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; Slf4j(topic "c.Sync01") public class Sync01 {private static int COUNTER 0;public static…

一次渲染十万条数据:前端技术优化(上)

今天看了一篇文章&#xff0c;写的是一次性渲染十万条数据的方法&#xff0c;本文内容是对这篇文章的学习总结&#xff0c;以及知识点补充。 在现代Web应用中&#xff0c;前端经常需要处理大量的数据展示&#xff0c;例如用户评论、商品列表等。直接渲染大量数据会导致浏览器性…

【C++登堂入室】类和对象(下)

目录 一、 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 二、static成员 2.1 概念 2.2 特性 三、友元函数 3.1 友元函数 3.2 友元类 四、内部类 五、 再次理解类和对象 结尾 一、 再谈构造函数 1.1 构造函数体赋值 在创建对象时&#xf…

【C++】多态的认识和理解

个人主页 文章目录 ⭐一、多态的概念&#x1f384;二、多态的定义及实现1.多态的构成2.实现多态的条件3.虚函数的概念4.虚函数的重写和覆盖5.析构函数的重写6.协变7.override和 final关键字8.重载、重写/覆盖、隐藏这三者的区别 &#x1f3e0;三、纯虚函数和抽象类的关系&#…

三目运算及简单案例

//三目运算是用来简化判断的 //所谓的三目 有三个表达式组成 //表达式一 条件表达式 返回的结果是布尔 //表达式二 条件表达式结果为true 时 返回的结果 //表达式三 条件表达式结果为false 时 返回的值 int age 20; //获取用…

树莓派驱动之spi回环测试

开启spi sudo raspi-config选择Interfacing options,选择spi打开 lsmod可以看到spi_bcm2835 短接MISO和MOSI 编写回环代码spitest.c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <string.h>…

【Python机器学习】NLP信息提取——命名实体与关系

我们希望计算机能够从文本中提取信息和事实&#xff0c;从而略微理解用户所说的内容。例如&#xff0c;当用户说“提醒我星期一浏览***.org网站”&#xff0c;我们希望这句话触发当天后下一个周一的日程或者提醒的操作。 要触发上述操作&#xff0c;需要知道“我”代表一种特定…

【devops】devops-gitlab之部署与日常使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

新任项目经理,如何快速接手项目

新任项目经理踏上管理岗位&#xff0c;面临着前所未有的挑战与机遇。如何快速适应角色&#xff0c;有效管理团队&#xff0c;确保项目顺利推进&#xff0c;是每一位新任项目经理必须面对的。 一、深入了解项目与团队 1、项目定位与规划 新任项目经理应对项目进行全面的调研与…

初识zookeeper

Zookeeper介绍 Zookeeper是Apache Hadoop项目下的一个子项目&#xff0c;是一个树形目录服务。 Zookeeper是一个分布式的、开源的分布式应用程序的协调服务。 Zookeeper提供的主要功能包括&#xff1a; 配置管理分布式锁集群管理 Zookeeper数据模型 Zookeeper客户端常用命…

windows使用tcpdump.exe工具进行抓包教程

windows主机安装一些抓包工具可能有些不方便&#xff0c;这里有一个tcpdump.exe工具直接免安装&#xff0c;可以直接使用进行抓包。&#xff08;工具下载见 附件&#xff09; tcpdump.exe使用教程 如下&#xff1a; 1&#xff1a;tcpdump -D 可查看网络适配器(注意前面的编号)…

分治算法专题(一)——快速排序之【三路划分】

目录 1、分治算法简介 2、算法应用【leetcode】 2.1 题一&#xff1a;颜色分类 2.1.1 算法原理 2.2.1 算法代码 2.2 题二&#xff1a;排序数组——数组分三块原理 2.2.1 算法原理 2.2.2 算法代码 2.3 题三&#xff1a;数组中的第K个最大元素 2.3.1 算法原理 2.3.2 算…

各大平台统遭入侵??区块链市场遭攻击损失近3亿!

今年&#xff0c;全球发生多起骇人听闻的勒索入侵软件攻击事件&#xff0c;黑客组织利用各种手段和技术&#xff0c;不断试图突破网络安全防线&#xff0c;窃取敏感信息、破坏系统运行&#xff0c;甚至进行勒索和敲诈&#xff0c;使得网络安全问题日益凸显其重要性和紧迫性。 S…

Mysql分组取最新一条记录

文章目录 Mysql分组取最新一条记录1. 数据准备1. 方法1&#xff1a;使用子查询获取每个组的最大时间戳&#xff0c;然后再次查询获取具体记录&#xff08;如果时间戳是唯一的&#xff09;2. 方法2&#xff1a;使用窗口函数&#xff08;MySQL 8.0&#xff09;3. 方法3&#xff1…

TikTok跨境电商营销新策略:品牌联盟与影响力经济的结合

随着TikTok成为全球化的社交和电商平台&#xff0c;也给跨境卖家提供了新的商机。境电商通过与其他知名品牌、网红或KOC建立品牌联盟&#xff0c;能够有效实现资源共享、优势互补&#xff0c;并推动市场扩张&#xff0c;带来更大的商业价值和品牌影响力。本文Nox聚星将和大家探…

鸿蒙开发协调布局CollapsibleLayout

鸿蒙开发协调布局CollapsibleLayout 首先鸿蒙我暂时没找到官方提供的协调布局&#xff0c;所以得自己自定义。 一、思路 可滚动头部、粘性头部、可滚动内容布局 可折叠区域高度可滚动头部高度-粘性头部高度 二、效果图 鸿蒙开发协调布局CollapsibleLayout 三、关键代码 //…

优思学院|如何从零开始自己学习六西格玛?

优思学院为学习六西格玛管理的学员&#xff0c;精心推荐了几本由浅入深、系统全面的书籍&#xff0c;帮助大家从入门到精通&#xff0c;逐步掌握六西格玛这一强大的管理工具。无论你是刚接触六西格玛的初学者&#xff0c;还是想在专业领域提升的高级学员&#xff0c;这几本书都…

【ARM】Trustzone和安全架构

Trustzone的基本概念&背景和历史 什么是Trustzone&#xff1f; 什么是TEE&#xff1f; Trustzone是一个技术&#xff0c;是一个技术的设计&#xff0c;一个安全架构&#xff0c;既不是软件也不是硬件。 TEE (Trusted Execution Environment) 可信执行环境。就是依托Trust…