进程的重要函数

进程的重要函数:

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.rhkb.cn/news/426362.html

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

相关文章

运用Java实现倒计时功能

这个功能其实是比较好实现的&#xff0c;一般来说java中实现倒计时有两种方法&#xff1a; 1、使用 scheduledexecutorservice创建一个可重复执行的任务&#xff0c;直到时间到&#xff1a; ScheduledExecutorService 是 Java 中一种用于安排延迟或定期任务的工具。我们可以使…

云计算第四阶段------CLOUD Day4---Day6

Cloud DAY4 项目架构图&#xff1a; 环境准备&#xff1a; 主机名称IP地址配置logstash192.168.1.27最低配置4核8G #书接上文&#xff0c;我们在华为云平台租了几台云服务器&#xff0c;这次买一台性能好的服务器&#xff0c;作为logstash软件部署的载体。 今天给小伙伴们带来…

低代码门户技术:构建高效应用的全新方式

什么是低代码门户技术&#xff1f; 低代码门户技术是一种利用低代码平台构建企业门户网站或应用的技术。门户通常是企业内部和外部用户访问信息和应用的集中平台。低代码门户技术通过图形化界面和预置组件&#xff0c;允许用户快速搭建和定制这些门户平台&#xff0c;而无需深…

TCP并发服务器的实现

一请求一线程 问题 当客户端数量较多时&#xff0c;使用单独线程为每个客户端处理请求可能导致系统资源的消耗过大和性能瓶颈。 资源消耗&#xff1a; 线程创建和管理开销&#xff1a;每个线程都有其创建和销毁的开销&#xff0c;特别是在高并发环境中&#xff0c;这种开销…

性能测试的复习3-jmeter的断言、参数化、提取器

一、断言、参数化、提取器 需求&#xff1a; 提取查天气获取城市名请求的响应结果&#xff1a;城市对查天气获取城市名的响应结果进行响应断言和json断言对查天气获取城市名添加用户参数 1、步骤 查看天气获取城市名 json提取器&#xff08;对响应结果提取、另一个接口请求…

简单了解微服务--黑马(在更)

认识微服务 单体架构 不适合大型复杂项目 微服务架构 将单体结构的各个功能模块拆分为多个独立的项目 拆取的独立项目分别开发&#xff0c;在部署的时候也要分别去编译打包&#xff0c;分别去部署&#xff0c;不同的模块部署在不同的服务器上&#xff0c;对外提供不同的功能…

小间距LED显示屏的技术原理分析

在现代显示技术领域&#xff0c;小间距LED显示屏以其卓越的显示效果和灵活的应用场景&#xff0c;逐渐成为市场的新宠。本文将深入探讨小间距LED显示屏的技术原理&#xff0c;分析其在显示领域的应用优势。 A、小间距LED显示屏的基本概念 小间距LED显示屏是指LED灯珠之间的间距…

linux hadoop-3.3.6 hbase-2.5.7

软件下载 hadoop https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz 可以直接下载到本地&#xff0c;也可以直接下载进虚拟机中 如果速度较慢&#xff0c;可以用&#xff1b;另一个 wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common…

spring-boot-maven-plugin插件打包和java -jar命令执行原理

文章目录 1. Maven生命周期2. jar包结构2.1 不可执jar包结构2.2 可执行jar包结构 3. spring-boot-maven-plugin插件打包4. 执行jar原理 1. Maven生命周期 Maven的生命周期有三种&#xff1a; clean&#xff1a;清除项目构建数据&#xff0c;较为简单&#xff0c;不深入探讨&a…

spring容器创建bean过程中使用到的几个factory

文章目录 前述BeanFactoryFactoryBeanObjectFactory 前述 spring我们可以理解为一个帮我们管理bean的容器&#xff0c;使用spring框架之前创建bean都是通过new的方式&#xff0c;使用spring框架之后&#xff0c; 我们只需要告诉spring框架我们有那些bean&#xff0c;它会帮我们…

k8s证书过期处理

证书一共分为 根CA&#xff08;ca.crt&#xff09; master各组件的证书&#xff08;包括etcd、apiserver、front-proxy、controller-manager等各种&#xff09; kubelet证书 k8s证书有效期说明&#xff1a; 1、原生版本有效期master节点&#xff1a; /etc/kubernetes/ssl/…

YOLOv10改进系列,YOLOv10损失函数更换为Powerful-IoU(2024年最新IOU),助力高效涨点

改进前训练结果: 改进后的结果: 摘要 边界框回归(BBR)是目标检测中的核心任务之一,BBR损失函数显著影响其性能。然而,观察到现有基于IoU的损失函数存在不合理的惩罚因子,导致回归过程中锚框扩展,并显著减缓收敛速度。为了解决这个问题,深入分析了锚框扩展的原因。针…

基于 K8S kubernetes 的常见日志收集方案

目录 1、日志对我们来说到底重不重要&#xff1f; 2、常见的日志收集方案 2.1 EFK 2.2 ELK Stack 2.3 ELKfilebeat 2.4 其他方案 2、elasticsearch组件介绍 3、filebeat组件介绍 3.1 filebeat和beat关系 3.2 filebeat是什么&#xff1f; 3.3 Filebeat工作原理 3.4 …

ELFK日志分析平台,架构和通信

整个架构&#xff0c;加上跳板机&#xff0c;总共12台机器 技术方案&#xff1a; 1. 配置nfs服务器&#xff0c;为web集群提供共享网络文件系统 # 部署 NFS 服务 [rootnfs ~]# dnf install -y nfs-utils [rootnfs ~]# vim /etc/exports /var/webroot 192.168.1.0/24(rw,…

xml重点笔记(尚学堂 3h)

XML:可扩展标记语言 主要内容(了解即可) 1.XML介绍 2.DTD 3.XSD 4.DOM解析 6.SAX解析 学习目标 一. XML介绍 1.简介 XML(Extensible Markup Language) 可扩展标记语言&#xff0c;严格区分大小写 2.XML和HTML XML是用来传输和存储数据的。 XML多用在框架的配置文件…

剖析 MySQL 数据库连接池(C++版)

目录 ☀️0. 前言 &#x1f324;️1. 数据库连接池概述 ⛅1.1 服务器与数据库交互 ⛅1.2 MySQL 数据库网络模型 ⛅1.3 MySQL 连接驱动安装 ⛅1.4 同步&#xff08;synchronous&#xff09;连接池与异步&#xff08;asynchronous&#xff09;连接池 ⛅1.5 同步连接池和异…

记录开发一个英语听力训练网站

背景 在当前全球经济衰退的背景下&#xff0c;IT相关的工作在国内的竞争也是越来越激烈&#xff0c;为了能够获得更多的可能性&#xff0c;英语的学习也许能为程序员打开一扇新的窗户&#xff0c;比如很多远程的工作尤其是国际化背景的工作团队&#xff0c;英语的协作沟通是必…

yolov8-obb中存在的一个bug

yolov8支持OBB目标检测,且能提供较好的性能。 但是最近在使用yolov8-obb的过程中,发现yolov8-obb存在一个bug。即训练数据如果包含不带旋转角度的水平目标时,训练出的模型,经常会输出垂直的检测框,需要旋转90度以后才能得到最终结果。把yolov8-obb相关的源码阅读一遍才发…

初始爬虫5

响应码&#xff1a; 数据处理&#xff1a; re模块&#xff08;正则表达式&#xff09; re模块是Python中用于正则表达式操作的标准库。它提供了一些功能强大的方法来执行模式匹配和文本处理。以下是re模块的一些常见用法及其详细说明&#xff1a; 1. 基本用法 1.1 匹配模式 …

STM32 的 RTC(实时时钟)详解

目录 一、引言 二、RTC 概述 三、RTC 的工作原理 1.时钟源 2.计数器 3.闹钟功能 4.备份寄存器 四、RTC 寄存器 1.RTC_TR&#xff08;Time Register&#xff0c;时间寄存器&#xff09; 2.RTC_DR&#xff08;Date Register&#xff0c;日期寄存器&#xff09; 3.RTC_S…