linux應用軟件編程之多任務(進程)詳解
一、多任務概述
1.定義:
讓系統(tǒng)具備同時處理多個任務的能力
2.實現(xiàn)過程
- 多進程
- 多線程
- 進程間通信
二、進程概述
1.定義
一個正在運行的程序稱為一個進程,其運行過程中需要消耗內(nèi)存和CPU。

2.程序和進程的區(qū)別
程序 進程
靜態(tài)的數(shù)據(jù)集合,存儲在硬盤空間 是一個程序動態(tài)執(zhí)行的過程,需要消耗內(nèi)存和CPU
程序運行起來可以產(chǎn)生進程 進程具備動態(tài)生命周期,從產(chǎn)生到調(diào)度再到消亡
一個程序可以產(chǎn)生多個進程 一個進程中也可執(zhí)行多個程序
3.進程的產(chǎn)生
進程產(chǎn)生時,操作系統(tǒng)都會為其分配0-4G的虛擬內(nèi)存空間。操作系統(tǒng)內(nèi)存區(qū)如下圖所示:

(1)內(nèi)核: 1 文件管理;2. 進程管;3. 內(nèi)存管理。
(2)棧區(qū):1.保存局部變量;2.函數(shù)的形參和返回值;3.保存函數(shù)的調(diào)用關(guān)系(保護現(xiàn)場和恢復現(xiàn)場)。
(3)堆區(qū):1. 由開發(fā)人員手動分配;2. 使用完要手動釋放。
(4)數(shù)據(jù)區(qū):
- data段:1. 已初始化的全局變量 ;2. 已初始化的靜態(tài)變量。
- bss段:1.未初始化的全局變量 ; 2. 未初始化的靜態(tài)變量(static)-->bss段初始時按位清0。
- 字符串常量區(qū):保存字符串常量 "hello world"
(5)文本區(qū):1. 存放指令代碼 ;2. 存放常量。
4.進程的調(diào)度
- CPU:
由于CPU數(shù)據(jù)處理速度快,因此是“宏觀并行,微觀串行”。
- cpu調(diào)度算法
1、時間片輪詢算法
2、先來先服務,后來后服務(任務隊列)
3、短作業(yè)優(yōu)先調(diào)度
4、高優(yōu)先級先執(zhí)行,低優(yōu)先級后執(zhí)行
5.進程的狀態(tài)
- 操作系統(tǒng)的三態(tài)圖:

- Linux操作系統(tǒng)的進程狀態(tài):

- 各進程狀態(tài):
1.運行態(tài)(用戶運行態(tài)、內(nèi)核運行態(tài)) R
正在執(zhí)行,且被CPU任務調(diào)度所執(zhí)行的進程
2.就緒態(tài) R
正在執(zhí)行,沒有CPU任務調(diào)度執(zhí)行的進程(只缺少cpu)
3.可喚醒等待態(tài) S
也稱為睡眠態(tài),阻塞等待資源的進程
4.不可喚醒等待態(tài) D
不想被CPU任務調(diào)度所打斷的進程任務可以設(shè)置為不可喚醒等待態(tài)
5.暫停態(tài) T
被暫停執(zhí)行的進程
6.僵尸態(tài) Z
進程執(zhí)行結(jié)束,空間沒有被回收
7.結(jié)束態(tài) X
進程執(zhí)行結(jié)束,空間被回收
6.進程的消亡
- 進程執(zhí)行結(jié)束(進程退出)
- 回收進程資源空間
三、進程相關(guān)的命令
- 父進程:產(chǎn)生子進程的進程稱為父進程
- 子進程:父進程產(chǎn)生出來的新進程即為該父進程的子進程
1. ps -aux
查看進程相關(guān)參數(shù):PID、狀態(tài)、CPU占有率、內(nèi)存占有率

- USER:創(chuàng)建者
- PID:進程的ID號
- %CPU:CPU占有率
- %MEM:內(nèi)存占有率
- TTY:當前進程所關(guān)聯(lián)的終端
- STAT:當前進程的狀態(tài)值(帶“+”號表示前臺進程,不帶“+”號表示后臺進程)
- START TIME:進程創(chuàng)建的時間
- COMMAND:進程的名稱(init進程是操作系統(tǒng)啟動的第一個進程)
ps -aux | grep ./a.out
- |:管道 :前面命令的輸出作為后面命令的輸入
- grep:字符串查找:在輸入中查找和后面字符串相關(guān)的數(shù)據(jù)

2. top
動態(tài)查看進程的相關(guān)參數(shù):CPU占有率、內(nèi)存占有率
——按照CPU、內(nèi)存占有率的高低進行排列的

- PR、NI:表示進程的優(yōu)先級,值越小,優(yōu)先級越高
- TIME+:進程運行的時間
3. ps -ef查看該進程的ID和父進程ID

4. pstree查看進程的產(chǎn)生關(guān)系
pstree -p
查看進程的產(chǎn)生關(guān)系(有PID號)

pstree -sp 進程PID號
查看某個指定的進程的產(chǎn)生關(guān)系

5.kill
kill -信號的編號/信號的名稱 PID
向進程發(fā)送信號,讓進程的狀態(tài)發(fā)生變化


由第一張圖片中可以看出20429進程一開始是在R+運行狀態(tài),執(zhí)行kill相關(guān)命令,其進程被殺死。
結(jié)束一個進程的三種表示形式:
kill -9 PID kill -SIGKILL PID killall -9 進程名稱
kill -l
查看系統(tǒng)支持的信號

- 9——SIGKILL——殺死信號
- 19——SIGSTOP——暫停態(tài)信號
- 18——SIGCONT——喚醒信號
+前臺進程后臺進程
6. jobs查看當前終端的后臺進程

7.fg
[ fg 后臺進程編號]
讓后臺進程切換成前臺進程


四、進程相關(guān)的編程
1.實現(xiàn)進程的步驟
進程創(chuàng)建 : fork()
- getpid():獲取當前進程自己的PID號
- getppid():獲取當前進程父進程的PID號
進程調(diào)度:操作系統(tǒng)完成
進程消亡:
- 1.進程退出:return、exit()相關(guān)函數(shù)
- 2.回收資源空間:wait()、waitpid()
2.進程創(chuàng)建函數(shù)
pid_t fork(void);
功能:通過拷貝父進程產(chǎn)生一個新的子進程
- 子進程完全拷貝父進程0-3G的虛擬內(nèi)存空間
- 子進程拷貝父進程PCB(進程控制塊)塊中的部分內(nèi)容:PID不拷貝
返回值:
- >0:父進程 ,是子進程的PID號
- ==0:子進程
- -1 :出錯

3.示例程序
使用fork函數(shù)創(chuàng)建新進程,
- 父進程打印自己的PID和自己子進程的pid
- 子進程中打印自己的PID和父進程的PID
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc , const char *argv[])
{
pid_t pid = fork();
if(pid > 0)
{
while(1)
{
printf("I am father pid = %d sonpid = %d \n",getpid(),pid);
sleep(1);
}
}
else if(0 == pid)
{
while(1)
{
printf("I am son pid = %d ppid = %d \n",getpid(),getppid());
sleep(1);
}
}
else
{
perror("fork error");
}
return 0;
}注意:
1. 子進程完完整整拷貝父進程0-3G虛擬內(nèi)存空間。
2. 父子進程棧區(qū)、數(shù)據(jù)區(qū)、文本區(qū)、堆區(qū)完全獨立,數(shù)據(jù)不共享
3. 要想共享數(shù)據(jù),需要使用進程間通信方式實現(xiàn)

例如以下程序:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc , const char *argv[])
{
pid_t pid = fork();
int num = 0;
if(pid > 0)
{
num = 100;
while(1)
{
printf("I am father pid = %d sonpid = %d num = %d\n",getpid(),pid,num);
sleep(1);
}
}
else if(0 == pid)
{
num = 1000;
while(1)
{
printf("I am son pid = %d ppid = %d num = %d\n",getpid(),getppid(),num);
sleep(1);
}
}
else
{
perror("fork error");
}
return 0;
}運行結(jié)果如下:

3.進程退出函數(shù)
(1)main中return
#include <stdio.h>
#include <stdlib.h>
int fun()
{
return 0;
}
int main(int argc, const char *argv[])
{
int i = 15;
while (i--)
{
printf("PID = %d\n", getpid());
sleep(1);
}
return 0;
}(2) exit ()、_exit() :結(jié)束一個進程
- exit (0) : 正常退出
- exit (非0) :由于進程產(chǎn)生了某種問題,需要主動退出進程
#include <stdio.h>
#include <stdlib.h>
int fun()
{
exit(0);
return 0;
}
int main(int argc, const char *argv[])
{
fun();
printf("hello world\n");
return 0;
}4.回收資源空間:
wait()、waitpid()
僵尸進程:進程退出后,但其資源空間未被父進程回收
如何避免僵尸進程產(chǎn)生:
1. 子進程退出后,父進程及時為其回收資源空間
2. 讓該進程成為一個孤兒進程,結(jié)束時被操作系統(tǒng)中的系統(tǒng)進程回收
孤兒進程:父進程先消亡,其對應的子進程成為一個孤兒進程,會被系統(tǒng)進程所收養(yǎng)
(守護類的進程)
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
pid_t pid = fork();
if (pid > 0)
{
while (1)
{
printf("I am father : pid = %d, sonpid = %d\n", getpid(), pid);
sleep(1);
}
}
else if (0 == pid)
{
int i = 15;
while (i--)
{
printf("I am son : pid = %d, ppid = %d\n", getpid(), getppid());
sleep(1);
}
}
else
{
perror("fork error");
}
return 0;
}
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
pid_t pid = fork();
if (pid > 0)
{
int i = 10;
while (i--)
{
printf("I am father : pid = %d, sonpid = %d\n", getpid(), pid);
sleep(1);
}
}
else if (0 == pid)
{
int i = 20;
while (i--)
{
printf("I am son : pid = %d, ppid = %d\n", getpid(), getppid());
sleep(1);
}
}
else
{
perror("fork error");
}
return 0;
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux設(shè)置虛擬內(nèi)存的教學與實戰(zhàn)教程
這篇文章主要給大家介紹了關(guān)于Linux設(shè)置虛擬內(nèi)存教學與實戰(zhàn)的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-03-03
Centos7安裝ElasticSearch 6.4.1入門教程詳解
這篇文章主要介紹了Centos 7安裝ElasticSearch 6.4.1入門教程詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05
htaccess 將所有請求重定向到某個URL地址的規(guī)則
htaccess 將所有請求重定向到某個URL地址的規(guī)則,需要的朋友可以參考下。2011-04-04
win7中VMware安裝CentOs7搭建Linux環(huán)境教程
這篇文章主要為大家詳細介紹了win7中VMware虛擬機安裝CentOs7搭建Linux環(huán)境教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Linux IO多路復用之epoll網(wǎng)絡(luò)編程
今天小編就為大家分享一篇關(guān)于Linux IO多路復用之epoll網(wǎng)絡(luò)編程,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12

