進程的基本概念:
進程是一個具有獨立功能的程序關於某個數據集合的一次運行活動。它可以申請和擁有系統資源,是一個動態的概念,是一個活動的實體。它不只是程序的代碼,還包括當前的活動,通過程序計數器的值和處理寄存器的內容來表示。
(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;
}
查看進程狀態: