进程的基本概念:
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
(1)课本概念:程序的一个执行实例,正在执行的程序等。
(2)内核观点:担当分配系统资源(CPU时间、内存)的实体。
操作系统在管理进程时,先将其描述起来,再对其组织管理。
描述进程-PCB:
(1)进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
(2)课本上称之为PCB(process control block)(进程控制块),Linux操作系统下的PCB是:task_struct。
task_struct-PCB的一种:
(1)在Linux中描述进程的结构体叫做task_struct。
(2)task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
查看进程:
通过ps和top获取进程信息:
进程的基本状态:
1.进程的三种基本状态:
(1)就绪态:进程已分配到资源,只要再获得CPU,便可立即执行。
(2)执行态:进程已获得CPU,其程序正在执行状态。
(3)阻塞态:进程由于发生某事件暂时无法继续执行时的状态。
2. 三种状态的转换:
3.进程的状态:
(1)R运行状态(runing):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
(2)S睡眠状态(sleeping):意味着进程在等待事件完成。(可中断睡眠)
(3)D磁盘休眠状态(Disk sleep):也叫不可中断睡眠状态。
(4)T停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止(T)进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行。
(5)X死亡状态(dead):这个状态只是一个返回状态,不会在任务列表里看到这个状态。
创建进程:
1.通过系统调用创建进程-fork
2.fork有两个返回值,当fork成功时,子进程返回0,父进程返回子进程的进程号;当fork失败,父进程返回错误。
3.父进程子进程代码共享,数据各自开辟空间,私有一份;子进程就是对父进程进行写实拷贝。
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int ret=fork();
if(ret<0)
{
perror("fork!");
return 1;
}
else if(ret==0) //子进程
{ //child proc
printf("I am child:%d!,ret:%d\n",getpid(),ret);
}
else
{ //father proc //父进程
printf("I am father:%d!,ret:%d\n",getpid(),ret);
}
sleep(1);
return 0;
}
结果如图所示:
僵尸进程:
(1)僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回码时就会产生僵死(尸)进程。
(2)僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
(3)只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t id=fork();
if(id<0)
{
perror("fork");
return 1;
}
else if(id>0)
{ //father
printf("father[%d] is sleeping...\n",getpid());
sleep(30);
}
else
{
printf("child[%d] is begin Z...\n",getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}
查看运行状态:
孤儿进程:
父进程先退出,子进程就被称之为“孤儿进程”。孤儿进程被1号init进程领养。#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t id=fork();
if(id<0)
{
perror("fork");
return 1;
}
else if(id==0)
{
printf("I am child,pid: %d\n",getpid());
sleep(10);
}
else
{
printf("I am father,pid: %d\n",getpid());
sleep(5);
exit(0);
}
return 0;
}
查看进程状态: