进程的创建、多任务及退出

一、创建进程

1、并发与并行

为了提高计算机执行任务的效率,一般采用的解决方案就是能够让多个任务同时进行,可以使用 并发
并行两种方式
并行 : cpu 多核的支持下,实现物理上的同时执行
并发 : 在有限的 cpu 核芯的情况下 , 利用快速交替 ( 时间片轮转 ) 执行来达到宏观上的同时执行
总结:并行是基于硬件完成,而并发则可以使用软件算法来完成,可以创建多个进程并发执行来完成任务

二、进程创建

1、fork() 函数

通过调用 fork() 函数,则会产生一个新的进程。调用 fork() 函数的进程叫做 父进程 ,产生的新进程则为 进程
函数头文件
#include <sys/types.h>
#include <unistd.h>
函数原型
pid_t fork(void);
函数功能
创建一个子进程
函数返回值
成功 : 返回给父进程是子进程的 pid, 返回给子进程的是 0
失败 : 返回 -1, 并设置 errno
代码
// 创建一个子进程,并打印 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;
}
运行结果
问题 1 :为什么显示两次 "hello fork"
是因为打印语句在两个进程中都运行了
问题 1 :为什么两次显示结果有差异?
如果父进程在子进程打印之前结束,则会回到终端命令后继续执行子进程;如果子进程的
打印语句在父进程结束之前执行,则会在回到终端命令前执行完毕。
代码
// 创建一个子进程,并打印进程的pid
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid==-1){perror("fork");return -1;}printf("pid = %d,Hello fork.\n",getpid());return 0;
}

结果:

2 、父子进程

通过 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;
}
文件描述符的拷贝
每个进程都会维护一个文件表项,即文件描述符与文件指针的映射表
Linux 内核中有一个 struct file 结构体来管理所有打开的文件
当子进程拷贝了父进程文件描述符后,则会共享文件状态标志与文件偏移量等信息

三、进程多任务

1、父子进程执行不同的任务

使用 fork() 函数之后,会创建子进程, fork() 之后的代码会在父子进程中都执行。
如果父子进程执行相同的任务,则正常执行
如果父子进程执行不同的任务,则需要利用 fork() 函数返回值
例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{printf("multitask.\n");pid_t pid = fork();if(pid == -1){perror("fork");return -1;}else if(pid==0){printf("child process task.\n");exit(EXIT_SUCCESS);}else{printf("parent process task.\n");}printf("parent and child task.\n");return 0;
}

2、创建多个进程、

在创建多个进程时 , 最主要的原则是 由父进程统一创建,统一管理,不能进行递归创建
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid == -1){perror("fork");return -1;}else if(pid==0){printf("child process <%d> is running.....\n",getpid());sleep(2);printf("child process <%d> ready to exit.\n",getpid());exit(EXIT_SUCCESS);}else{// 父进程中继续创建子进程pid = fork();if(pid == -1){perror("fork");return -1;}else if(pid == 0){printf("child process <%d> isrunning.....\n",getpid());sleep(4);printf("child process <%d> ready toexit.\n",getpid());exit(EXIT_SUCCESS);}printf("parent process task.\n");}printf("parent and child task.\n");return 0;
}

四、进程的退出

在进程结束时,需要释放分配给进程的地址空间以及内核中产生的各种数据结构
资源的释放需要通过 exit 函数或者 _exit 函数来完成
在程序结束时,会自动调用 exit 函数

1、exit_exit

exit

函数头文件
#include <stdlib.h>
函数原型
void exit(int status);
函数功能
结束进程,并刷新缓冲区
函数参数
status: 退出状态值
在系统中定义了两个状态值 : EXIT_SUCCESS 正常退出, EXIT_FAILURE 异常退出,具体定义在
stdlib.h
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
代码 1 :创建一个子进程,让子进程延时 2s 后退出
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid == -1){perror("fork");exit(EXIT_FAILURE);}else if(pid==0){printf("child process <%d> is running.....\n",getpid());sleep(2);exit(EXIT_SUCCESS);printf("child process <%d> ready to exit.\n",getpid());}else{sleep(5);}return 0;
}
代码 2 :说明 exit 函数会刷新缓冲区
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid == -1){perror("fork");exit(EXIT_FAILURE);}else if(pid==0){printf("child process <%d> is running.....",getpid()); // 注意此处没有换行符sleep(2);exit(EXIT_SUCCESS);printf("child process <%d> ready to exit.\n",getpid());}else{sleep(5);}return 0;
}
备注:发现执行 printf("child process <%d> is running.....",getpid()); 语句时并不是立即打
印,而是会延迟 2s
_exit
_exit 函数与 exit 函数功能相同
函数头文件
#include <unistd.h>
函数原型
void _exit(int status);
函数参数
status: 进程退出的状态值
代码 1: 创建一个子进程,使用 _exit 函数让子进程延时 2s 后退出
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid == -1){perror("fork");exit(EXIT_FAILURE);}else if(pid==0){printf("child process <%d> is running.....\n",getpid());sleep(2);printf("child process <%d> ready to exit.\n",getpid());_exit(EXIT_SUCCESS);}else{sleep(5);}return 0;
}
代码 2: 创建一个子进程,使用 _exit 函数让子进程延时 2s 后退出
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{pid_t pid = fork();if(pid == -1){perror("fork");exit(EXIT_FAILURE);}else if(pid==0){// 此条语句没有换行符printf("child process <%d> is running.....",getpid());sleep(2);_exit(EXIT_SUCCESS);}else{sleep(5);}return 0;}
1.3 exit _exit 的不同
_exit() 属于 系统调用 ,能够使进程停止运行,并释放空间以及销毁内核中的各种数据结构
exit() 基于 _exit() 函数实现,属于库函数 , 会自动刷新 I/O 缓冲区

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

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

相关文章

60 序列到序列学习(seq2seq)_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录一、理论知识比喻机器翻译Seq2seq编码器-解码器细节训练衡量生成序列的好坏的BLEU(值越大越好)总结 二、代码编码器解码器损失函数训练预测预测序列的评估小结练习 一、理论知识 比喻 seq2seq就像RNN的转录工作一样&#xff0c;非常形象的比…

Percona Monitoring and Management

Percona Monitoring and Management (PMM)是一款开源的专用于管理和监控MySQL、MongoDB、PostgreSQL

netty之NettyClient半包粘包处理、编码解码处理、收发数据方式

前言 Netty开发中&#xff0c;客户端与服务端需要保持同样的&#xff1b;半包粘包处理&#xff0c;编码解码处理、收发数据方式&#xff0c;这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了&#xff1b;半包粘包、编码解码等&#xff0c;为此在本章节我们…

C++和OpenGL实现3D游戏编程【连载12】——游戏中音效的使用

1、游戏中音效的使用 前面我们实现了图片纹理的显示功能,是不是感觉到非常的简单。那么今天我们就继续说下游戏声音的实现。音效也是游戏的灵魂,只有搭配了美妙动听的音效以后,游戏才能令人耳目一新,与玩家产生良好的效果。 音效文件最常用的可分为两种,分别为.wav和.mp3…

SQL Server中关于个性化需求批量删除表的做法

在实际开发中&#xff0c;我们常常会遇到需要批量删除表&#xff0c;且具有共同特征的情况&#xff0c;例如&#xff1a;找出表名中数字结尾的表之类的&#xff0c;本文我将以3中类似情况为例&#xff0c;来示范并解说此类需求如何完成&#xff1a; 第一种&#xff0c;批量删除…

Mysql 学习——项目实战

MySQL 学习——项目实战 项目出处 博主&#xff1a;Asmywishi Linux-Ubuntu启动Mysql sudo mysqlData preparation Create Database and Table Create database : create database mysql_example1;Start database : use mysql_example1;Create Student table : # 学生表…

使用VBA快速将文本转换为Word表格

Word提供了一个强调的文本转表格的功能&#xff0c;结合VBA可以实现文本快速转换表格。 示例文档如下所示。 现在需要将上述文档内容转换为如下格式的表格&#xff0c;表格内容的起始标志为。 示例代码如下。 Sub SearchTab()Application.DefaultTableSeparator "*&quo…

828华为云征文 | 基于华为云Flexus云服务器X搭建部署——AI知识库问答系统(使用1panel面板安装)

&#x1f680;对于企业来讲为什么需要华为云Flexus X来搭建自己的知识库问答系统&#xff1f;&#xff1f;&#xff1f; 【重塑知识边界&#xff0c;华为云Flexus云服务器X引领开源问答新纪元&#xff01;】 &#x1f31f; 解锁知识新动力&#xff0c;华为云Flexus云服务器X携…

【算法】DFS 系列之 穷举/暴搜/深搜/回溯/剪枝(上篇)

【ps】本篇有 9 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1&#xff09;全排列 .1- 题目解析 .2- 代码编写 2&#xff09;子集 .1- 题目解析 .2- 代码编写 3&#xff09;找出所有子集的异或总和再求和 .1- 题目解析 .2- 代码编写 4&#xff09;全排列 II…

C语言语句、语句分类及注释

文章目录 一、语句和语句分类二、注释&#x1f355;注释是什么&#xff1f;为什么写注释&#xff1f;1. /**/的形式2. //的形式3. 注释会被替换 三、随机数的生成1.rand函数2.srand函数3.time函数4.设置随机数的范围 四、C99中的变长数组五、问题表达式解析表达式1表达式2表达式…

手机实时提取SIM卡打电话的信令声音-(题外、插播一条广告)

手机实时提取SIM卡打电话的信令声音-(题外、插播一条广告) 前言 在去年的差不多这个时候&#xff0c;我们做了一遍外置配件的选型&#xff0c;筛选过滤了一批USB蓝牙配件和type-c转usb的模块。详情可参考《外置配件的电商价格和下载链接的选型.docx》一文&#xff1a;蓝牙电话…

FireRedTTS - 小红书最新开源AI语音克隆合成系统 免训练一键音频克隆 本地一键整合包下载

小红书技术团队FireRed最近推出了一款名为FireRedTTS的先进语音合成系统&#xff0c;该系统能够基于少量参考音频快速模仿任意音色和说话风格&#xff0c;实现独特的音频内容创造。 FireRedTTS 只需要给定文本和几秒钟参考音频&#xff0c;无需训练&#xff0c;就可模仿任意音色…

Python基础语句教学

Python是一种高级的编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简单易读的语法和强大的功能而闻名&#xff0c;被广泛用于科学计算、Web开发、数据分析等领域。 Python的应用领域广泛&#xff0c;可以用于开发桌面应用程序、Web应用、游戏、数据分析、人工智能等…

基于SSM的列车订票管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的列车订票管理系统3拥有两种角色&#xff1b;管理员、用户 管理员&#xff1a;用户管理、车票管理、购票指南管理、系统管理等 用户&#xff1a;发布帖子、登录注册、购票等 1.…

C++继承与菱形继承(一文了解全部继承相关基础知识和面试点!)

目的减少重复代码冗余 Class 子类(派生类) &#xff1a; 继承方式 父类&#xff08;基类&#xff09; 继承方式共有三种&#xff1a;公共、保护、私有 父类的私有成员private无论哪种继承方式都不可以被子类使用 保护protected权限的内容在类内是可以访问&#xff0c;但是在…

Python | Leetcode Python题解之第452题用最少数量的箭引爆气球

题目&#xff1a; 题解&#xff1a; class Solution:def findMinArrowShots(self, points: List[List[int]]) -> int:if not points:return 0points.sort(keylambda balloon: balloon[1])pos points[0][1]ans 1for balloon in points:if balloon[0] > pos:pos balloo…

ubuntu18.04安装教程

window分区 制作启动盘 插入 按F12进入启动选项页面&#xff0c;选择usb启动 选择install ubuntu 进入安装页面 选择中文&#xff08;简体&#xff09; 键盘布局选择英语&#xff08;美国&#xff09; 选择正常安装 等一小会儿 选择其他选项 分区 包括500mb系统分区 1000…

通信工程师笔记

第一章 1.支撑网是使业务网正常运行,增强网络功能,提供全网服务质量以满足用户要求的网络。 2.常见的有线通信线路包括&#xff08;1&#xff09;双绞线&#xff0c;&#xff08;2&#xff09;同轴电缆&#xff0c;&#xff08;3&#xff09;光纤等&#xff0c;无线通信线路是…

鼓组编曲:鼓编写技巧之进鼓加花编写

为了方便快速查阅和运用一些教程笔记&#xff0c;个人记性有时可能不是特别好&#xff0c;所以只能疯狂做笔记了&#xff0c;制作以下图文笔记&#xff0c;仅供参考…… 鼓组加花 鼓的变动 进鼓后然后就可以动次打次了 下面是2个底鼓的加花

北京市大兴区启动乐享生活 寻味大兴 美食嘉年华 系列促销费活动

北京市大兴区启动乐享生活 寻味大兴 系列促销费活动 区商务局副局长 兰莉 致开幕辞 区餐饮行业协会会长 董志明 介绍活动内容 2024年9月30日&#xff0c;由大兴区商务局主办、大兴区餐饮行业协会承办&#xff0c;并得到高米店街道和大兴绿地缤纷城大力支持的“乐享生活 寻味大…