1.基本概念
从书本上来说:进程是程序执行的一个实例。
从内核观点来说:担当分配系统资源(CPU时间,内存)的实体。
2.描述进程-PCB
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合,这种集合称之为PCB(process control block),Linux操作系统下的PCB是: task_struct。
其内容包含如下:
1.进程标识符(PID):别名进程号,描述本进程的唯一标识符,用来区别其他进程。
2.内存指针: 包括程序代码和进程相关数据的指针,指向程序的地址空间。还有和其他进程共享的内存块的指针 。
3.状态: 任务状态,退出代码,退出信号等。
4.优先级: 相对于其他进程的优先级。
5.程序计数器: 程序中即将被执行的下一条指令的地址。
6.上下文数据:保存上次执行时寄存器当中的值。
7.I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
8.记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
3.创建进程-初识fork函数
运行:man fork,查看fork函数相关信息。其函数功能为创建一个新的进程(子进程)。
fork函数返回值:
小于0,表示返回失败。
等于0,表示返回到子进程当中。
大于0,表示返回到父进程当中。
代码实现:
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid=fork();
if(pid<0)
{
perror("fork");
return 0;
}
else if(pid==0)
{
//child
//pid_t getpid(void):谁调用获取谁的进程PID
//pid_t getppid(void):谁调用获取谁的父进程PPID
printf("i am child,pid=[%d],ppid=[%d]\n",getpid(),getppid());
}
else
{
//father
printf("i am father,pid=[%d],ppid=[%d]\n",getpid(),getppid());
}
return 0;
}
父进程调用fork函数,创建子进程,子进程的PCB拷用父进程,通过返回值的不同,可以让父子进程执行不同的代码。
通过ps -ef可以查看进程的PID以及其父进程的PID(PPID)。
4.组织进程
系统内核使用双向链表来组织进程的task_struct信息
5.查看进程
进程的信息可以通过 /proc 系统文件夹查看,例如:查看PID为1的进程信息。
6.进程状态
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在 Linux内核里,进程有时候也叫做任务)。
R(running):运行状态 ,并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
S(sleeping):可中断睡眠状态,意味着进程在等待事件完成。
D(disk sleep):磁盘睡眠状态,不可被打断,在这个状态的 进程通常会等待IO的结束。
T(stopped):暂停状态,可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。
t:跟踪状态,gdb调试时是这个状态。
X:死亡状态,这个状态只是一个返回状态,不会在任务列表里看到这个状态。
Z:僵尸状态
查看进程状态信息:ps aux | grep [进程名称]