当前位置: 首页 > news >正文

c语言多任务处理(并发程序设计)

. 多任务处理(并发程序设计)
1. 何谓多任务处理?
多任务处理是指同一时间内处理或者执行多个独立的功能任务,这样的事物处理方法
称为多任务处理。

 2. 多任务处理方式的背景?
应用程序中往往是要支持多种复杂功能,我们就不能按照以前,某个功能执行完毕后再执行下一个功能任务,
设计方式来设计程序,我们期望的是某些独立的功能任务可以在同一时间共同执行(并发),以提升程序的运行
效率,这样就需要多任务处理方式了。

 3. 多任务处理方式的实现
3.1  多进程
3.2  多线程

 4. 进程初步
4.1  基础概念
1) 进程:
统一认知:进程是程序的一次执行过程,是程序执行和资源管理的最小单元
2) 进程的资源信息描述 (PCB)
PCB(进程控制块):用于记录系统对进程资源,状态,标识符分配信息等等
本质是Linux内核提供的一个数据类型 (struct task_struct)来表示。
3) 进程的标识(PID)
PID(进程号):用来唯一标识系统中的一个进程,本质是非零的正整数。
4.2 进程特征  
4.2.1  独立性:进程一旦产生系统会为每一个进程分配4GB虚拟地址空间,每一个进程都运行在自己的
虚拟地址空间中,互不干扰
4.2.2  并发性:不同的进程可以在同一时间内同时运行;
4.2.3  异步性:由于进程要竞争CPU资源,所以会产生周期性的等待,也就是说进程其实并不是"齐头并进";
4.2.4  动态性:因为进程是程序执行过程,有创建及消亡的过程,
4.2.5  结构特征:
统会为每一个进程分配4GB虚拟地址空间,同时系统将该地址空间进行可结构划分,主要划分为
以下的内存结构,(自下而上)

           代码段
数据段
堆段
内存映射段
栈段
命令行参数段
环境变量存储段
4.3 进程的模式
4.3.1  内核模式:
不可被干扰,内核模式执行完毕,进程会转入用户模式:
4.3.2  用户模式
大部分情况下,进程都是运行在用户模式的,一旦遇到系统调用或者发生硬件中断,进行
将转入内核模式.

     4.4 进程的状态及状态转换

          基本状态:
1)   运行状态:   进程正在运行
2)   就绪状态:   进程已经获取除了CPU之外的所有资源,一旦分配CPU资源就可以运行
3)   阻塞状态:    进程因为等待某个事件的发生,暂停运行
4)   僵尸状态:   进程已经运行完毕,但是进程资源(PCB)没有被回收
5)   停止状态:   进程已经运行完毕,进程资源(PCB)被回收


状态转换:   详见  进程状态转换.bmp

      注意事项: 如果在实现多任务处理过程中,选择使用多进程解决方案,则一定要确保父进程不能先于子进程
退出,否则会造成程序已经运行结束的假象。而且使得子进程称为孤儿进程。

  5. 进程基础操作
5.1   进程创建
函数头文件    #include <unistd.h> 
#include <sys/types.h> 
函数原型:     pid_t fork(void) / pid_t vfork(void)
函数功能:    进程创建
函数参数:    无
函数返回值:  说明:fork/vfork 调用一次返回两次:
成功  子进程返回0
父进程返回子进程PID
失败 返回 -1, 错误码放在errno

          fork / vfork 区别:
1. fork 创建子进程成功后, 系统为子进程分配独立的地址空间
vfork 创建子进程成功后,子进程和父进程共享父进程的地址空间
2. fork 创建子进程成功后, 父子进程执行顺序取决于系统的调度
vfork 创建子进程成功后,子进程先于父进程运行,子进程只有在调用了
exit/_exit 及 exec函数簇,父进程才可以正常运行。
3. 应用场景:
1.在系统硬件资源充足的情况下,推荐使用fork创建进程,否则使用vfork,
2.在使用exec函数簇时,推荐使用vfork创建子进程,在子进程中利用exec启动新程序。

5.2   获取进程ID
函数头文件    #include <unistd.h> 
#include <sys/types.h> 
函数原型:     pid_t getpid(void) / pid_t getppid(void)
函数功能:    进程ID获取
函数参数:    无
函数返回值:  说明:getpid  返回自身进程ID:
getppid 返回父进程ID:                    
该函数调用不会失败 
5.3   进程退出
函数头文件    #include <unistd.h> 
#include <stdlib.h> 
函数原型:     void exit(int status) / void _exit(int status)
函数功能:    进程退出
函数参数:    status: 进程退出后传递给父进程的数据(status & 0377)
函数返回值:  无

exit / _exit 区别:
1.  exit 是标准库函数, _exit Linux内核函数
2.  exit 在进程退出前会处理IO缓存。
5.4   进程等待
函数头文件    #include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
函数原型:     pid_t wait(int *status) /pid_t waitpid(pid_t,pid,int *status,int option)
函数功能:    阻塞调用进程,直到某个子进程/指定子进程 退出
函数参数:    [OUT]status: 用户获取子进程退出值(需要利用 WEXITSTATUS 宏转换)
pid:  指定的子进程ID
option: 附加选项: 往往取值为0
函数返回值:  退出的子进程ID

说明: 进程等待的目的:
1. 父进程想要获取子进程退出值;如果父进程不关注子进程的退出值,status可以设为NULL
2. 回收子进程的进程资源。
3. 为了确保父进程不能先于子进程退出。

      5.5  进程中启动新程序
函数头文件    #include <unistd.h> 
函数原型:     int execl (const char *path,const char* arg,...);
int execlp(const char *file,const char* arg,...);
int execle(const char *path,const char* arg,...,char* const envp[]);

              int execv (const char *path,const char* argp[]);
int execvp(const char *file,const char* argp[]);
int execve(const char *path,const char* argp[],char* const envp[]);

        函数功能:    进程中启动新程序
函数参数:    path:待启动的应用程序路径
arg:  待启动的应用程序命令行参数,以程序名开始,NULL结束
argp: 存储待启动的应用程序命令行参数的字符指针数组,元素以程序名开始,NULL结束
envp:用户自定义环境变量数组(NULL结束),用于在启动新程序的同时,传递给新程序的数据。
函数返回值:  成功返回0
失败返回-1,错误码放置在errno          

          引申的知识点:  自定义环境变量

自定义环境变量的语法格式:
环境变量名(大写) = 环境变量值 (字符串)

            例子: NAME = TeacherYu
AGE  = 45
char* const envp[] = {"NAME = TeacherYu"," AGE  = 45",NULL};

      exec函数簇的区分:

函数名的第五个字符:    
l:  (list)    利用exec函数参数罗列被启动程序的命令行参数
v:  (vector)  用数组将被启动程序的命令行参数先存储起来,然后将数组传递给exec函数参数

         函数名的第六个字符:
无:  
p: (Path):系统会到PATH环境变量所代表的路径下去找寻待启动程序,如果未找到,exec函数调用失败
e: (enviorment): 在启动启动程序时,可以通过自定义环境变量向待启动程序传递数据。

http://www.lryc.cn/news/626665.html

相关文章:

  • iOS App 混淆工具实战 医疗健康类 App 的安全与合规保护
  • Elasticsearch 写入全链路:从单机到集群
  • [系统架构设计师]面向服务架构设计理论与实践(十五)
  • [element-plus] el-tree 拖拽到其他地方,不拖拽到树上
  • Vue3 element ui 给表格的列设置背景颜色
  • 晨控EtherCAT设备分配IP操作手册
  • LWIP的TCP协议
  • 在 Golang 中复用 HTTP 连接
  • 26_基于深度学习的茶叶等级检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • CTFshow系列——命令执行web38-40
  • Qt音乐播放器项目实践:本地持久化与边角问题处理
  • 小红书账号隔离:解决IP关联问题方案
  • 网络工程师考试重点:OSI七层模型TCP/IP四层模型解析
  • 【北京迅为】iTOP-4412精英版使用手册-第三十二章 网络通信-TCP套字节
  • yolo_RK3588系列(三)
  • 5.4 4pnpm 使用介绍
  • FreeRTOS---进阶知识1---列表的创建
  • SQL 中大于小于号的表示方法总结
  • Claude Code NPM 包发布命令
  • 内网安全——出网协议端口探测
  • Java开源工具Apache PDFBox(强大的处理 PDF文档工具:创建、读取、修改、解析和提取 PDF)
  • Apache ShenYu和Nacos之间的通信原理
  • 【Tech Arch】Apache Pig大数据处理的高效利器
  • Spring Boot 日志体系详解:配置与实战
  • 三、k8s 1.29 之 资源清单
  • 网络编程5(HTTPS)
  • 【考研408数据结构-08】 图论基础:存储结构与遍历算法
  • Linux的奇妙冒险——进程pcb第二讲
  • 云原生俱乐部-k8s知识点归纳(5)
  • SpringTask入门