1、進程
1.1什么是進程:進行中的程序(正在運行中的程序)-process過程
? ? ? ? 程序的一次執行過程 - 進程
? ? ? ? hello.c --? 程序源代碼
? ? ? ? a.out? ?--? 可執行程序
1.2程序和進程的關系:
????????程序<------>進程
1.3進程怎么來的:
? ? ? ? 程序->加載到內存(運行起來了)-->進程
1.4總結:
進程 ---動態---內存
程序---靜態----硬盤
1個程序可以對應一個或多個進程
1.5為什么需要進程
時間片輪轉
若要保存上次程序運行到哪了,則需記錄-程序的執行狀態
則需要進程這個概念了
描述和記錄,正在運行中的程序的相關信息。
進程的調度(操作系統,上下文的切換)(讓它看起來程序在并發運行,其實每個程序只能運行一小會,且(單核)cpu每次只執行一個程序)
進程的執行特點:微觀串行,宏觀并行。
最核心的目的:提高效率。
1.6進程的組成:
1、
程序 = 代碼 + 數據
bss --- 未初始化的數據 |
data --- 初始化了的數據 | 靜態區 | ---數據
text --- 正文段(代碼段)
bss -- 未初始化? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 棧
----? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 堆
data -- 已初始化? ? ? --------------./a.out------------>? ? ? ? ? ? ? bss
----? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????????????????????????????????????? ? ?data? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
text -- 代碼段? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?text
//linux系統下,程序的內存布局? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //進程的實體
棧
堆
靜態區
字符串常量區
代碼段? //c語言標準的內存布局
進程 -----
pcb---是一個結構體? ? Process Control Block
進程 = pcb塊 + 各個段(棧 | 堆 | bss | data | text)
1.7進程的生命周期:
通用三態模型:
linux系統下的狀態模型:
1.8觀察進程的命令:
1、top命令? :觀察進程? //類似任務管理器
2、ps
man ps /state
進程狀態代碼:
D uninterruptible sleep (usually IO)
R running or runnable (on run queue) ---就緒隊列中
S interruptible sleep (waiting for an event to complete)
T stopped(暫停態), either by a job control signal or because it is being traced.
*W paging (not valid since the 2.6.xx kernel)
*X dead (should never be seen)Z defunct ("zombie") process, terminated but not reaped(收尸) by its parent.
查看進程相關信息
1.就緒態、運行態 R
2.睡眠態、等待態
????????可喚醒等待態 S
????????不可喚醒等待態 D
3.停止態 T
4.僵尸態 Z
5.結束態
ps aux | grep 進程名 (pid號)? //當前進程的id號 及 狀態
此命令可以察看所有同名文件
ps -eLf?| grep 進程名 (pid號)? ?//可查看父進程id號
ppid(parent? process id)//父進程id
3、pstree
pstree -sp id號 //是兩個命令合起來 {pid號(如果不寫表示查看全部的)}
查看進程關系
init(1) (1號進程最早出現的一個進程)---- gnome-terminal(xxxx)----bash(xxxx)
4、kill
kill PID
kill 信號編號(-數字) 進程ID
發送信號+PID對應的進程,默認接收者關閉
kill -9 進程PID號 //殺死程序
kill -l //查看信號列表
killall 信號編號 程序名字
5、 fork()
????????pid_t fork();? ? ? 叉子
?? ?一次調用,會返回兩次。
?? ?子進程先運行和是父進程先進程,順序不確定。
?? ?變量不共享。
?? ?
?? ?子進程復制父進程的0到3g空間和父進程內核中的PCB,但id號不同。
?? ?
?? ?功能:通過該函數可以從當前進程中克隆一個同名新進程。
?? ??? ? ?克隆的進程稱為子進程,原有的進程稱為 父進程。
?? ??? ? ?子進程是父進程的完全拷貝。
?? ??? ? ?子進程的執行過程是從fork函數之后執行。
?? ??? ? ?
?? ??? ? ?子進程與父進程具有相同的代碼邏輯。
?? ?返回值:int 類型的數字。
?? ??? ??? ?在父進程中:成功 返回值是子進程的pid號 >0
?? ??? ??? ??? ??? ??? ?失敗 返回-1;
?? ??? ??? ?在子進程中:成功 返回值 0
?? ??? ??? ??? ??? ??? ?失敗 無
代碼示例:
int main()
{pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid >0 ){printf("father---\n");}else if (pid == 0 ){printf("child---\n");}
}
輸出:
代碼解釋:
?
父子進程獨立操作。
練習:
1、父子進程都死循環。
? ? ? ? a.結束父進程,查看當前系統中父子進程的狀態
????????b.結束子進程,查看當前系統中父子進程的狀態
#include<stdio.h>
#include<unistd.h>int main(int argc, const char *argv[]){pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid >0 ){while(1){printf("father---\n");} }else if (pid == 0 ){while(1){printf("child---\n");}}return 0;}
?a.結束父進程? ? //子進程成為后臺進程,孤兒進程 --- 子進程還在,父進程不在。(init收養子進程。以前的版本)
b.結束子進程? ?//子進程結束,父進程還在?父進程沒有去收尸 ---子進程呈僵尸態,若此時結束父進程,則子進程的實尸體被系統收養,但系統發現子進程已死則直接銷毀回收,不然僵尸態(戶口信息)會占用內存。
?2、
自己分別定義一個 static的變量 static int a = 0; 全局變量 int b = 1; 堆區 int *p = (int *)malloc(sizeof(int)); *p = 2; (做修改)父進程中 做加1的操作 ,子進程中做加2的操作 分別打印,查看效果! 同時可以查看一下父子進程的關系(pstree) 父子進程的狀態!
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int b = 1;int main(int argc, const char *argv[])
{static int a = 0;int *p = (int *)malloc(sizeof(int));*p = 2;pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}//父進程獨立代碼while(1){if(pid > 0){printf("father a = %d\n",a++);printf("father b = %d\n",b++);printf("father p = %d\n",(*p)++);}//子進程獨立代碼else if(pid == 0){printf("child a = %d\n",a++);printf("child b = %d\n",b++);printf("child p = %d\n",(*p)++);}sleep(1);}return 0;
}
?? 父子進程之間不會影響,誰先運行的順序由操作系統決定,盡可能公平、高效
?
3、面試題:
一次fork生成幾個進程??
他們之間的關系是什么樣的? //生成1個一共有兩個
如果兩次fork同時前后執行,會生成幾個進程? //共有(4)個進程
他們之間的關系如何表示,
有多少個子進程,
有沒有孫進程?有
4、fork()&&fork()|| fork() 總共有幾個進程?
有5個進程
5、
fork();
fork();
fork();? 一共有幾個進程?? //? 2^n個進程
?6、動態生成子進程,并打印輸出各自進程的pid號
#include<stdio.h>
#include<unistd.h>int main(int argc, const char *argv[]){pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid >0 ){while(1){printf("father---%d\n",getpid());} }else if (pid == 0 ){while(1){printf("child---%d\n",getpid());}}return 0;}