Linux 进程管理
一、进程的概念
1. 进程的定义
进程是程序在计算机上的一次执行实例,它是操作系统进行资源分配和调度的基本单位。
2. 进程与程序的区别
程序是一段静态的代码,它存储在磁盘上。
进程是程序在计算机上的一次执行实例,它具有动态性。进程包括程序的代码、数据和运行状态。
二、进程的状态
1、 运行态
进程正在CPU上执行。
2、就绪态
进程已经准备好执行,但CPU上正在执行其他进程。
3、等待态
进程正在等待某个事件的发生,如等待I/O操作完成。
4、停止态
进程被挂起,不再执行。
5、终止态
进程已经完成执行或因某种原因被终止。
三、进程的创建和终止
1. 进程的创建
进程的创建通常由以下几种方式:
(1)用户请求:用户通过命令行或图形界面启动程序。
(2)系统调用:通过系统调用fork()或clone()创建新进程。
(3)其他进程:一个进程通过fork()或clone()系统调用创建新进程。
2. 进程的终止
进程的终止通常由以下几种方式:
(1)正常终止:进程执行完毕或因某种原因主动退出。
(2)异常终止:进程因错误或异常而终止。
(3)外部终止:其他进程通过系统调用kill()终止进程。
四、进程的调度
1. 进程调度的概念
进程调度是指操作系统按照一定的算法选择进程执行的过程。Linux采用多级反馈队列调度算法,根据进程的优先级和等待时间进行调度。
2. 进程调度的算法
(1)先来先服务(FCFS):按照进程到达的顺序进行调度。
(2)短作业优先(SJF):根据进程的执行时间进行调度,优先执行短作业。
(3)优先级调度:根据进程的优先级进行调度,优先级高的进程优先执行。
(4)多级反馈队列调度:将进程分为多个队列,每个队列有不同的优先级和调度算法。
五、常用函数
1. fork()
创建一个新进程。
函数原型:pid_t fork(void);
返回值:成功创建子进程时,父进程返回子进程的进程ID,子进程返回0;失败时,父进程和子进程都返回-1。
2. exec()
执行一个新程序。
函数原型:int execve(const char *filename, char *const argv[], char *const envp[]);
参数:execve()函数的参数包括要执行的程序名、参数列表和环境变量列表。
返回值:exec()函数族在成功执行新程序后不会返回,只有失败时才会返回-1。
3. wait()
等待子进程结束。
函数原型:pid_t wait(int *status);
参数:wait()函数的参数是一个指向int类型的指针,用于存储子进程的退出状态。
返回值:成功时返回子进程的进程ID,失败时返回-1。
4. kill()
向进程发送信号。
函数原型:int kill(pid_t pid, int sig);
参数:kill()函数的参数包括进程ID和信号。
返回值:成功时返回0,失败时返回-1。
5. getpid()
获取当前进程的进程ID。
函数原型:pid_t getpid(void);
返回值:成功时返回当前进程的进程ID,失败时返回-1。
6. getppid()
获取当前进程的父进程ID。
函数原型:pid_t getppid(void);
返回值:成功时返回当前进程的父进程ID,失败时返回-1。
7. nice()
设置进程的优先级。
函数原型:int nice(int inc);
参数:nice()函数的参数包括优先级增量。
返回值:成功时返回0,失败时返回-1。
8. sched_yield()
主动让出CPU。
函数原型:int sched_yield(void);
返回值:成功时返回0,失败时返回-1。
9. exit()
终止当前进程。
函数原型:void exit(int status);
参数:exit()函数的参数包括退出状态。
返回值:无
10. sleep()
使进程睡眠一段时间。
函数原型:unsigned int sleep(unsigned int seconds);
参数:sleep()函数的参数包括睡眠时间。
返回值:成功时返回0,失败时返回-1。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid < 0) {
// fork失败
fprintf(stderr, "Fork failed\n");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// 子进程
printf("Child process: PID = %d\n", getpid());
execl("/bin/ls", "ls", "-l", NULL);
// 如果execl成功执行,则不会返回
fprintf(stderr, "Exec failed\n");
exit(EXIT_FAILURE);
} else {
// 父进程
printf("Parent process: PID = %d\n", getpid());
int status;
waitpid(pid, &status, 0);
printf("Child process terminated with status %d\n", status);
}
return 0;
}