进程相关内容
进程内容
- 进程类型
- 守护进程
- 进程的概念
- 查看进程信息
- 父子进程
- 创建子进程
- 进程结束 – exit/_exit
- 进程回收 –wait waitpid
进程类型
交互进程 (Interactive Process)
交互进程是由用户通过终端或图形界面直接启动的进程,例如我们在命令行输入的命令。它通常需要等待用户的输入,并在执行完成后直接返回输出。交互进程可以在前台或后台运行,前台的交互进程会占用终端,而后台进程不会阻塞终端。
批处理进程 (Batch Process)
批处理进程是按照调度器设定的时间批量执行的任务,不需要用户直接交互。它们通常由作业调度器 (如cron) 启动,以自动化运行一些任务。批处理进程在后台安静地执行任务,适用于需要定期或批量处理的任务,例如备份、日志处理等。
守护进程 (Daemon Process)
守护进程是一种在后台运行的长期服务进程,它们不与用户直接交互,通常在系统启动时自动启动。守护进程为系统提供各种服务,如网络服务 (如sshd)、文件系统服务 (如nfsd)、打印服务 (如cupsd) 等。守护进程的父进程通常是init (PID为1),以确保它们不会因为其他进程的终止而被意外杀死。
自己编辑的程序在运行时会成为一个 交互进程 或 批处理进程,具体取决于它是如何启动和运行的:
交互进程:
如果你在命令行中直接运行这个程序,例如通过 ./fb_display 启动,那么它就是一个交互进程,因为它是通过终端启动的并与用户交互。它会在运行完成后返回控制权给终端。
批处理进程:
如果你将程序配置为定时任务,让它自动运行(例如通过 cron 定时执行),那么它会成为一个批处理进程,因为它的执行是自动化的,不需要用户的实时操作或交互。
守护进程(可选):
如果你希望这个程序在后台持续运行并周期性地刷新屏幕(例如每隔几秒或几分钟自动更新帧缓冲区),则可以将它改写为一个守护进程,使它始终在后台运行。
守护进程
进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。
进程的概念
BSS段:BSS段通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。
数据段:数据段通常是指用来存放程序中已初始化的全局变量的一块内存区域。
代码段:代码段通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进后出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
查看进程信息
ps -el
ps -elf
F:表示进程的标志 (flags),用于描述进程的状态和属性。
S:表示进程状态,通常用单个字母表示,例如:
R:运行中(Running)。
S:睡眠(Sleeping)。
D:不可中断睡眠(通常用于 I/O 操作)。
Z:僵尸进程(Zombie)。
T:停止(Stopped)。
UID:启动该进程的用户 ID。
PID:进程 ID,用于唯一标识每个进程。
PPID:父进程 ID,即启动当前进程的进程的 ID。
C:CPU 使用率的百分比。
PRI:优先级 (priority),数值越小,优先级越高。
NI:调整优先级的 nice 值,值越小表示优先级越高。
ADDR:表示内存地址,通常用于调试目的。
SZ:进程所占用的虚拟内存大小,以 KB 为单位。
WCHAN:进程当前正在等待的内核函数。
STIME:进程启动的时间。
TTY:进程的终端名称,若没有控制终端,则显示为 ?。
TIME:进程使用的 CPU 时间总量。
CMD:启动该进程的命令和参数。
top 查看进程动态信息
ctrl+z 把运行的前台进程转为后台并停止。
./test & 把test程序后台运行
jobs 查看后台进程
bg 将挂起的进程在后台运行
fg 把后台运行的进程放到前台运行
父子进程
要点:
1 子进程只执行fork之后的代码
2.父子进程执行顺序是操作系统决定的。
子进程继承了父进程的内容
父子进程有独立的地址空间,互不影响
若父进程先结束
子进程成为孤儿进程,被init进程收养
子进程变成后台进程
若子进程先结束
父进程如果没有及时回收,子进程变成僵尸进程
创建子进程
#include <unistd.h>
pid_t fork(void);
创建新的进程,失败时返回-1
成功时父进程返回子进程的进程号,子进程返回0
通过fork的返回值区分父进程和子进程
pid_t pid;if ((pid = fork()) < 0) {perror(“fork”); return -1;}else if (pid == 0) {printf(“child process : my pid is %d\n”, getpid());}else {printf(“parent process : my pid is %d\n”, getpid());}
进程结束 – exit/_exit
#include <stdlib.h>
#include <unistd.h>
void exit(int status);
void _exit(int status);
void _Exit(int status);
结束当前的进程并将status返回
exit结束进程时会刷新(流)缓冲区
进程回收 –wait waitpid
#include <sys/wait.h>
pid_t wait(int *status);
成功时返回回收的子进程的进程号;失败时返回EOF
若子进程没有结束,父进程一直阻塞
若有多个子进程,哪个先结束就先回收
status 指定保存子进程返回值和结束方式的地址
status为NULL表示直接释放子进程PCB,不接收返回值
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int option);
成功时返回回收的子进程的pid或0;失败时返回EOF
pid可用于指定回收哪个子进程或任意子进程
status指定用于保存子进程返回值和结束方式的地址
option指定回收方式,0 或 WNOHANG 阻塞和不阻塞
进程返回值和结束方式
WIFEXITED(status)
判断子进程是否正常结束
WEXITSTATUS(status)
获取子进程返回值
WIFSIGNALED(status)
判断子进程是否被信号结束
WTERMSIG(status)
获取结束子进程的信号类型