进程的重要函数

news2024/11/13 6:33:45

进程的重要函数:

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()
{
	// 标准IO
	write(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.coloradmin.cn/o/2146023.html

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

相关文章

【FFT】信号处理——快速傅里叶变换【通俗易懂】

快速傅里叶变换&#xff08;Fast Fourier Transform, FFT&#xff09;是一种用于将信号从时间域转换到频率域的算法。 傅里叶变换的核心思想是&#xff1a;任何周期性信号都可以分解成多个不同频率的正弦波或余弦波的叠加。 简单来说&#xff0c;FFT可以帮助我们理解一个信号…

使用 Internet 共享 (ICS) 方式分配ip

设备A使用dhcp的情况下&#xff0c;通过设备B分配ip并共享网络的方法。 启用网络共享&#xff08;ICS&#xff09;并配置 NAT Windows 自带的 Internet Connection Sharing (ICS) 功能可以简化 NAT 设置&#xff0c;允许共享一个网络连接给其他设备。 打开网络设置&#xff1…

力扣之1075.项目员工I

文章目录 1. 1075.项目员工I1.1 题干1.2 准备数据1.3 解法1.4 结果截图 1. 1075.项目员工I 1.1 题干 项目表 Project&#xff1a; -------------------- | Column Name | Type | -------------------- | project_id | int | | employee_id | int | -------------------- 主键…

『小白可入』VSPD虚拟串口工具——从此告别硬件串口调试

一、下载VSPD工具 工具已上传至百度云&#xff0c;在以下地址下载&#xff1a; VSPD下载链接&#xff1a;通过百度网盘分享的文件&#xff1a;我的资源 链接&#xff1a;https://pan.baidu.com/s/1x2eoQYg6erqs__CQgT5j6Q?pwd4211 提取码&#xff1a;4211 二、安装 1.解压后的…

2024年Apple Search Ads(简称:苹果ASA):开展有效活动的秘诀

当谈到为应用程序启动广告活动时&#xff0c;许多人会立即想到Android。然而&#xff0c;这并不总是最好的选择&#xff0c;因为iOS设备在多个国家和地区占据市场主导地位。在这些地区&#xff0c;定位ios用户可以带来更大的成功。 您可以通过各种渠道在iOS上投放广告&#xff…

最低成本的游戏串流方案分享 如何自己打造云电脑?

今天教大家如何最低成本实现串流 出门在外也可以随时随地游玩端游大作 硬件准备&#xff1a;一台电脑 手机/平板一台 软件&#xff1a;Gameviewer远程 为啥不用moonlight等其他软件呢 因为设置公网穿透等复杂操作对小白来说不太友好 而GameViewer从安装到使用仅需一键 对比同类…

PostgreSQL技术内幕10:PostgreSQL事务原理解析-日志模块介绍

文章目录 0.简介1.PG日志介绍2.事务日志介绍3.WAL分析3.1 WAL概述3.2 WAL设计考虑3.2.1 存储格式3.2.2 实现方式3.2.3 数据完整性校验3.3 check ponit 4.事务提交日志&#xff08;CLOG&#xff09;4.1 clog存储使用介绍4.2 slru缓冲池并发控制 0.简介 本文将延续上一篇文章内容…

好用的网页翻译插件

软件介绍 「火山翻译&#xff0c;开箱即用免配置&#xff0c;完全免费无广告&#xff0c;开发的多语言翻译插件&#xff0c;基本涵盖众多小语种及国际通用语言的翻译&#xff0c;支持网页一键翻译、划词翻译、英语词典、生词本、吐司弹词记忆等丰富能力。 下载方式 请看文章…

【AprilTag】视觉定位实战 | 使用 ROS 驱动的 USB 摄像头进行相机标定与 AprilTag 识别

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

Matlab进行频率切片小波变换

Matlab进行频率切片小波变换(FSWT)源代码&#xff0c;将一维信号生成时频图。 输入信号可以是任何一维信号&#xff0c;心电信号、脑电信号、地震波形、电流电压数据等。 相比连续小波变换(CWT)&#xff0c;频率切片小波变换(Frequency Slice Wavelet Transform,FSWT)是一种更具…

C# 使用代码清理 以及禁用某个代码清理

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

鸿蒙Harmony应用开发,数据驾驶舱 项目结构搭建

对于一个项目而言&#xff0c;在拿到我们的开发任务后&#xff0c;我们最重要的就是技术的选型。选型定下来了之后我们便开始脚手架的搭建&#xff0c;然后开始撸代码&#xff0c;开搞. 首先我们需要对一些常见依赖库的引入 我们需要再oh-package.json5的dependencies节点下面…

strlen和sizeof

在 C 语言中&#xff0c;strlen 和 sizeof 是两个非常常用的操作符&#xff0c;但它们的作用和用途有很大的不同。下面详细解释这两个操作符&#xff1a; strlen strlen 是一个函数&#xff0c;定义在 <string.h> 头文件中&#xff0c;用于计算一个以空字符&#xff08…

华为OD机试 - 字符串划分(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

注意,传统的提示工程对新模型o1可能失效:来自OpenAI官方的4条提示词建议!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

Flink系列知识之:Checkpoint原理

Flink系列知识之&#xff1a;Checkpoint原理 在介绍checkpoint的执行流程之前&#xff0c;需要先明白Flink中状态的存储机制&#xff0c;因为状态对于检查点的持续备份至关重要。 State Backends分类 下图显示了Flink中三个内置的状态存储种类。MemoryStateBackend和FsState…

linux设置常见开机自启动命令

本文介绍了三种开机自启的方式&#xff0c;重点介绍使用systemctl的方式自启动的 方式一、修改 /etc/rc.d/rc.local 文件 /etc/rc.d/rc.local 文件会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要自己的脚本在开机后被运行的话&#xff0c;可以将自己脚本路径加到…

Kubernetes从零到精通(12-Ingress、Gateway API)

Ingress和Gateway API都是Kubernetes中用于管理外部访问集群服务的机制&#xff0c;但它们有不同的设计理念和适用场景。它们的基本原理是通过配置规则&#xff0c;将来自外部的网络流量路由到Kubernetes集群内部的服务上。 Ingress/Gateway API和Service Ingress/Gateway API…

边缘计算智能网关的功能应用与优势-天拓四方

在物联网的世界中&#xff0c;数以亿计的设备不断产生、传输和处理数据。然而&#xff0c;传统的云计算架构在面对这些实时性要求高、数据量庞大的物联网数据时&#xff0c;常常面临着网络延迟、带宽限制和安全风险等问题。这时&#xff0c;边缘计算智能网关作为一种新兴的技术…

图书馆座位预约系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;图书馆管理&#xff0c;座位信息管理&#xff0c;预约选座管理&#xff0c;签到信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;论坛&#xf…