C++学习笔记39:进程概念

时间:2023-03-08 17:26:06

进程的基本概念

  • 进程是描述程序执行过程和资源共享的基本单位
  • 主要目的:控制和协调程序的执行

进程相关函数

  • 用户与组ID函数
  • 创建进程:system(),fork(),exec()
  • 终止进程:kill()
  • 等待进程终止:wait(),waitpid()

进程组

  • 定义:由一个或多个相关联的进程组成,目的是为了进行作业控制
  • 进程组的主要特征:信号可以发送给进程组中的所有进程,并使该进程组中的所有进程终止,停止,或者继续运行
  • 每个进程都属于某个进程组

进程组函数

  获取进程组ID:pid_t getpgid(pid_t pid);

  设置进程组ID:int setpgid(pid_t pid ,pig_t pgid);

会话(session)

  • 会话为一个或多个进程组的集合,包括登录用户的全部活动,并具有一个控制终端
  • 登录进程为每个用户创建一个会话,用户登录shell进程成为会话首领,其PID设为会话ID
  • 非会话首领进程通过调用setsid()函数创建新会话,并成为首领

进程组函数

  • 获取会话ID:pid_t getsid(pid_t pid);
  • 设置会话ID:pid_t setsid();

信号(signal):进程通讯机制

  • 信号是发送给进程的特殊异步消息
  • 当进程接收到信息时立即处理,此时并不需要完成当前函数调用甚至当前代码行
  • Linux系统中有多种信号,各具备不同的意义;系统以数字标识不同的信号,程序一般以名称引用之

系统信号

  缺省处理逻辑:终止进程,生成内核转储文件

  使用kill -l命令可查看操作系统支持的信号列表,不同的系统可能有所不同

进程间发送的信号

  • SIGTERM,SIGKILL:终止进程信号,前者是请求(接收信号的进程可以忽略之),后者是强制
  • SIGUSR1,SIGUSR2:用户自定义信号,可用于向进程发送命令

信号处理

  进程接收到信号后,根据信号配置进行处理

  缺省配置:在程序没有处理时,确定信号该如何处理

  程序处理信号的方式,按照信号处理例程的函数指针定义一个函数,然后调用

  sigaction()函数:设置信号配置

  

处理信号时的注意事项:

  • 信号是异步操作,当处理信号时,主程序非常脆弱
  • 信号处理例程应该尽可能的短小,它甚至会被新信号中断
  • 尽量不要在信号例程中实施I/O操作,也不要频繁调用系统函数或者库函数
  • 在信号处理例程中进行复杂的赋值操作也是危险的,它可能不是原子操作,因而在可能在执行时被中断
  • 如果需要赋值,使用sig_atomic_t 类型的全局变量(在Linux中等价于int,即允许整数或指针赋值,更大尺寸数据不允许)
#include <signal.h>//处理信号的头文件
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
sig_atomic_t sigusr1_count = ;
extern "C" {void OnSigUsr1(int signal_number) { ++sigusr1_count; }}
int main()
{
std::cout << "pid:" << (int)getpid() << std::endl;
struct sigaction sa;
memset(&sa, , sizeof(sa));
sa.sa_handler = &OnSigUsr1;
sigaction(SIGUSR1, &sa, NULL);
sleep();//在终端中输入kill -s SIGUSR1 pid,信号计数器将递增
std::cout << "SIGUSR1 counts:" << sigusr1_count << std::endl;
return ;
}