Linux系統程式設計(六)程序與執行緒
1、程序組
程序組代表一個或多個程序的集合,父程序建立子程序時預設子程序與父程序屬於同一個程序組,程序組ID等於組長程序ID,(組長程序ID等於其組程序ID)
可以通過kill -SIGKILL -程序組ID 將所有的程序全部殺死。組長程序可以建立一個程序組,只要程序組中有一個程序存在,程序組就存在,與組長程序是否中止無關。
程序組生存週期:程序組建立到最後一個程序離開(中止或者轉移到另一個程序)
程序可以為自己或者子程序設定程序組id。
下面舉個例子:
$ cat | cat | cat | wc -l $ ps ajx PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND2943 20628 20628 2943 pts/0 20628 S+ 1000 0:00 cat 2943 20629 20628 2943 pts/0 20628 S+ 1000 0:00 cat 2943 20630 20628 2943 pts/0 20628 S+ 1000 0:00 cat 2943 20631 20628 2943 pts/0 20628 S+ 1000 0:00 wc -l $ kill -9 -20628 # 殺死程序組中的所有程序 # Killed $ kill -9 20628 # 殺死父程序 # 0 寫管道被殺死返回0,最終所有程序執行完畢,返回值為0
2、會話
組長程序不能建立會話,建立一個會話可以使用setsid方法,建立一個會話要注意以下內容:
呼叫程序不能是程序組組長,該程序會變成新會話的首程序
該程序成為一個新程序組的組長程序
新會話丟棄原有的控制終端,該會話沒有控制終端
建立新會話時,先呼叫fork,父程序中止,子程序呼叫setsid
控制終端型別:
TTY: 文字終端
pts/0: 虛擬終端
? : 無終端
3、守護程序
Daemon程序,Linux中的後臺服務程序,通常獨立於控制終端並且週期性地執行某種任務或等待處理某種任務或等待處理某些發生的事件,一般以d結尾的名字,守護程序不會因為使用者登出而停止。
建立守護程序模型:呼叫setsid
a. fork建立子程序,父程序退出
b. 在子程序中建立會話
c. 改變當前工作目錄 chdir,防止佔用可解除安裝的檔案系統
d. 重設檔案許可權掩碼,防止繼承的檔案建立遮蔽字拒絕某些許可權
e. 關閉檔案描述符,繼承的開啟檔案不會用到,浪費系統資源,無法解除安裝
f. 執行業務邏輯
給出一個例子:
#include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char** argv) { pid_t pid = fork(); if(pid < 0) { perror("fork error"); exit(1); } else if(pid > 0) { exit(0); } pid = setsid(); if(pid == -1) { perror("setsid fail"); exit(1); } chdir("/home/may"); umask(0022); close(STDIN_FILENO); int fd = open("/dev/null", O_RDWR); if(fd == -1) { perror("open /dev/null fail"); } dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); while(1); return 0; }
4、執行緒
程序:獨立地址空間,有PCB,最小的資源分配單位
執行緒:有獨立的PCB,但是沒有獨立的地址空間,最小的執行單位:LWP:light weight process,輕量級的程序
通過 $ ps -Lf pid,可以檢視程序中的執行緒
執行緒共享資源
a. 檔案描述符表
b. 每種訊號的處理方式(mask不共享)
c. 當前工作目錄
d. 使用者ID 和 組ID
e. 記憶體地址空間(.text 程式碼段 / .data / .bss / .heap/ 共享庫)
執行緒非共享資源
a. 執行緒id
b. 處理器現場和棧指標(核心棧)
c. 獨立的棧空間
d. errno 變數(全域性變數,在data段中但是不共享)
e. 訊號遮蔽字
f. 排程優先順序
執行緒優缺點
優點:
提高程式併發、開銷小、資料通訊共享資料方便
缺點:
庫函式不穩定、除錯困難、對訊號支援不好
程序中建立執行緒之後,程序就會退化成為執行緒,程序可以看作為是獨享程序空間的執行緒......