linux系統編程(3)

一 線程間同步

同步:相互之間配合完成一件事情
互斥:保證訪問共享資源的完整性(有你沒我)

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
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章