一 線程間同步
同步:相互之間配合完成一件事情
互斥:保證訪問共享資源的完整性(有你沒我)
POSIX 線程中同步:使用信號量實現
信號量 : 表示一類資源,它的值表示資源的個數
對資源訪問:
p操作(申請資源) [將資源的值 - 1]
....
V操作(釋放資源) [將資源的值 + 1]
1.定義信號量
sem_t sem ;
2.初始化信號量
int sem_init(sem_t *sem, int pshared, unsigned int value);
參數:
@sem 信號量
@pshared 0:線程間使用
@value 初始化的信號量的值
返回值:
成功返回0,失敗返回-1
3.P操作
int sem_wait(sem_t *sem);
4.V操作
int sem_post(sem_t *sem);
二 進程間通信(進程間數據交互)
(1)傳統進程間通信方式
[1]無名管道
[2]有名管道
[3]信號
(2)System 5 IPC對象進程間通信方式
[1]消息隊列
[2]共享內存
[3]信號燈集
(3)socket通信
(4)Android系統中增加Binder進程間通信方式
Linux 支持以上所有進程間通信方式
三 管道進程間通信
(1)無名管道
特點:
只能用於具有親緣關係進程間通信(具有親緣關係的進程具有數據拷貝動作(複製父進程創建子進程))
int pipe(int pipefd[2]);
功能:創建一個無名管道
參數:
@pipefd 獲取操作無名管道的文件描述符 pipefd[0]:讀無名管道 pipefd[1]:寫無名管道
返回值:
成功返回0,失敗返回-1
(2)管道讀寫規則
讀端存在 ,寫管道 ---->只要管道沒有滿,都可以寫入數據到管道
讀端不存在,寫管道 ---->此時寫管道沒有意義,操作系統會發送SIGPIPE殺死寫管道的進程
寫端存在, 讀管道 ---->此時管道中讀取數據,管道中沒有數據,讀阻塞
寫端不存在,讀管道 ---->此時管道中讀取數據,管道中沒有數據,此時不阻塞,立即返回,返回值0
(3)有名管道
特點:可以用於任意進程間通信,它是一種特殊的文件,在文件系統存在名字,
而文件中存放的數據是在內核空間,而不是在磁盤上
1.創建一個有名管道文件
int mkfifo(const char *pathname, mode_t mode);
@pathname 有名管道存在的路徑
@mode 有名管道的權限
返回值:
成功返回0,失敗返回-1
2.打開有名管道文件
open
如果有名管道的一端以只讀的方式打開,會阻塞,直到另一端以寫(只寫或讀寫)的方式打開
如果有名管道的一端以只寫的方式打開,會阻塞,直到另一端以讀(只讀或讀寫)的方式打開
3.讀寫操作
read /write
4.關閉管道文件
close(fd);
四 信號
信號是異步進程間通信方式
進程對信號的響應方式:
<1>忽略
SIGKILL 和 SIGSTOP 不能忽略
<2>捕捉
當進程收到信號,此時執行的信號處理函數
<3>默認
大部分信號對進程的默認操作方式都是殺死進程
子進程狀態發生改變的時候,操作系統向父進程發送SIGCHLD,默認對它處理方式是忽略
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:設置進程對信號處理方式
參數:
@signum 信號的編號
@handler
SIG_IGN : 忽略信號
SIG_DFL : 使用默認處理方式
函數名 : 捕捉方式處理
返回值:
成功返回handler,失敗返回SIG_ERR
練習:
如何進行不阻塞,不輪訓方式回收殭屍態子進程
2.在進程中設置一個定時器
unsigned int alarm(unsigned int seconds);
參數:
@seconds 定時的時間,以秒爲單位
注意:
一旦定時時間完成,操作系統就會向進程發送SIGALRM信號
A進程:
讀文件,寫管道
A進程結束條件:文件沒有數據可讀
B進程:
讀管道,寫文件
B進程結束條件:在寫端關閉,讀端不阻塞,如果管道中沒有數據,讀管道會返回0
linux系統編程(3)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.