基于Linux的进程编程 | C/C++
文章目录
一、进程的基本概念
1.进程的定义
进程是描述程序执行过程和资源共享的基本单位
主要目的:控制和协调程序的执行
2.linux下进程相关函数
用户与组ID:参阅上一讲:https://blog.****.net/qq_38801934/article/details/103142068
创建进程:system(),fork(),exec()
终止进程:kill()
等待进程终止:wait(),waitpid()
3.进程组
由一个或者多个相关进程组成,目的是为了进行作业控制。
进程组的主要特征:信号可以发送给进程组中的所有进程,并使该进程组中的所有进程终止、停止或运行。
每个进程组都属于某个进程组
4.进程组函数
获取进程组ID:pid_t getpgid(pid_t pid);
- 返回pid进程的进程组ID;若pid为0,则返回当前进程的进程组ID;出错时返回-1,并设有errno值。
设置进程组ID:int setpgid(pid_t pid,pid_t pgid);
- 若pid为0,则使用调用者PID;若pgid为0,则将pid进程的进程PID设为进程组ID;成功时返回0,出错时返回-1,并设errno值。
5.会话(session)
- 会话为一个或多个进程组的集合,包括登录用户的全部活动,并具有一个控制终端
- 登录进程为每各用户创建一个会话,用户登录shell进程成为会话首领,其PID设为会话ID
- 非会话首领进程通过调用setid()函数创建新会话,并成为首领
进程组函数
获取会话ID:pid_t getsid(pid_t pid);
- 返回pid进程的会话ID;若pid为0,则返回当前进程会话ID;成功时返回会话ID,出错时返回-1,并设errno值。
设置会话ID:pid_t setsid();
- 成功时返回新创建的会话ID,出错时返回-1,并设errno值
二、信号(signal):是一种进程通讯机制
- 信号量是发送给进程的特殊异步消息
- 当进程接受到信息时立即处理,此时并不需要完成当前函数调用甚至当前代码行。
- LInux操作系统中有多种信号,具有不同的含义;系统以数字标识不同的信号,程序一般以名称引用信号;
系统信号
- 系统信号缺省时处理逻辑:终止进程;生成内核转储文件;忽略
- 使用“kill -l”命令可查看操作系统支持的信号列表,不同的系统可能有所不同。
进程间发送的信号
- SIGTERM、SIGKILL:终止进程信号,前者是请求(接收信号的进程可以忽略他),后者是强制终止
- SIGUSER1、SIGUSER2:用户自定义信号,可用于向进程发送命令
信号处理
- 进程接受到信号之后,根据信号配置进行处理
- 缺省配置:在程序没有处理时,确定该信号如何处理
- 程序处理信号的方式:按照信号处理例程提供的函数指针来调用它所指定的函数
- sigaction()函数:设置信号配置(需要的时候再详细了解)
常用系统信号
信号处理注意事项
- 信号是一个异步操作,当处理信号时,主程序非常脆弱
- 信号处理例程尽可能小,它甚至可能会被新信号所中断
- 尽量不要在信号处理例程中实施I/O操作,也不要频繁调用系统函数或库函数
- 在信号处理例程中进行复杂的赋值操作也是危险的,他可能不是原子操作,因而有可能在执行期间被中断。
- 如果需要赋值,使用sig_atomic_t类新的全局变量(在linux中等价于int,亦即允许整数或指针赋值,更大尺寸数据不允许)
三、进程管理
1.进程创建
fork()返回两个值,分别给父子进程用
执行命令的基本模式:在程序中调用fork()创建一个子进程,让那后调用exec()在子进程中执行命令。
2.进程调度
进程调度策略:先进先出,时间片轮转,普通调度,批调度,高优先级优先
- 子进程与父进程的调度没有固定顺序;不能假设子进程一定会在父进程之后调度,也不能假设子进程一定会在父进程之前结束。
2.进程终止:kill()
3.僵尸进程
- 子进程已结束,但父进程未调用wait()函数等待
- 子进程已终止,但没有被正确清除,成为僵尸进程
清除子进程的手段
- 父进程调用wait()函数可确保子进程被清除
- 即使子进程在父进程调用wait()函数前已经死亡(成为僵尸),起退出状态也可以被抽取出来,然后被清除
- 未清除的子进程自动被inti进程领养
4.子进程的异步清除
SIGCHLD信号:子进程终止时,向父进程自动发送编写此信号处理例程,异步清理子进程
5.守护进程
创建守护进程步骤
- 创建新进程:新进程将成为未来的守护进程
- 守护进程的父进程退出:保证祖父进程确认父进程已结束,切守护进程不是组长进程
- 守护进程创建新进程组和新会话:并成为两者的首进程,此时刚创建的新会话还没有关联控制终端
- 改变工作目录:守护进程一般随系统启动,工作目录不应该继续使用继承的工作目录
- 重设文件权限掩码:不需要继承文件权限掩码
- 关闭所有文件描述符:不需要继承任何打开文件描述符
- 标准流重定向到/dev/null
- 创建成以根用户权限运行他或者随用户一起启动
守护进程创建函数deamon()
6.进程间的通信
6.1 管道:相关进程间的顺序通信
pipe的性质和意义
- 管道是允许单向通信的自动同步设备(半双工)
- 数据在写入端写入,在读取端读取
- 管道为串行设备,数据的读取顺序和写入顺序完全相同
管道的用途
- 只能用于有亲缘关系的进程,例如父进程和子进程之间通信
注意事项
- 管道的数据容量有限,一般为一个内存页面
- 如果写入速读超过读取速读,写入进程将阻塞,知道容量有空闲
- 如果读取速读超过写入速度,读取进程将阻塞,知道管道有数据
管道重定向
6.2 进程信号量:进程间通信的同步控制机制(System V信号量)
-
进程信号量用于进程同步
-
POSIX标准实现多线程同步
使用进程信号量注意事项
获取进程信号量
控制和管理进程信号量
清除进程信号量
union是共用存储区域,也就是所有的字段只有一个字段有效。
初始化进程信号量
信号量的获取与释放
信号量的等待与发布
实例
6.3 共享内存:允许多个进程读写同一片内存区域
LInux内存模型
获取共享内存
连接与拆卸共享内存
示例
6.4 映射内存:与共享内存意义相同,但与文件相连
6.5 消息队列:在进程间传递二进制块数据
和进程信号量有类似的地方,需要的时候再查阅
6.6 套接字(socket):支持无关进程,甚至不同计算机进行通信
7.进程池
动机及其概念
四、散装知识、问题点
1.真正的操作系统接口只有系统调用接口,其他所谓的图形接口、字符命令行接口都是建立在调用操作系统接口之上
2.红黑树是什么?作用领域在那儿?
数据库领域
3.linux系统中用file 文件名,可以得到file的一些信息。
4.什么是同步什么是异步?
针对不同的对象,如果是线程,那么同步就是两个线程同时使用一个资源;异步就是一个线程在使用资源其它线程等待它释放资源之后在使用。
如果是信号也是同样的道理,信号在等待进程对信号进行处理
5.进程池的工作原理是什么?