C實現進程間通訊(管道; 共享內存,信號量)

最近學習了操做系統的併發;如下是關於進程間實現併發,通訊的兩個方法。html

 

例子:linux

100000個浮點數的和。要求:git

(1)隨機生成100000個浮點數(父進程)github

(2)而後建立4個後代進程,分別求25000個浮點數的和數組

(3)父進程對4個後代進程的結果求和併發

(4)每一個子進程在屏幕上以格式(ID_k) Child_k sum: XXX」打印信息,函數

          其中k的取值爲14,表明子進程的編號,ID_k表示第k個子進程的IDXXX是該子進程計算的結果。post

(5)父進程在屏幕上以格式 「(IDParent direct sumYYY, sum from children: ZZZ」打印信息,學習

          其中ID表示父進程的IDYYY爲直接由100000個隨機數求和的值,ZZZ爲把4個子進程的結果相加的值。spa

 

 

1:利用管道進行進程間的通訊

用到下列函數

 pipe() from unistd.h

 sleep() 

 write(), read() 

 fork(); //建立子進程

 

管道只能用於具備親緣關係的進程,能夠將其看做一個文件,但有別於普通的文件, 管道一次只能夠被一個進程訪問,能實現互斥;

pipe(int fd[] ), 其參數爲長度爲2的int數組,分別表明讀端fd[0], 寫端fd[1], 在建立管道後,f d[0],fd[1]成爲文件描述符;

寫入(write)管道一端fd[1]的數據,在管道的另外一端fd[0]能夠被進程讀取(read);

代碼在這裏

 

2:利用共享內存實現通訊, 信號量實現互斥

共享內存使用瞭如下函數:

int shm_open(const char *name, int oflag, mode_t mode);  //建立或打開共享內存, 返回文件描述符

int ftruncate(int fd, off_t FILE_SIZE);  //調整共享內存空間大小

void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset ) //將文件映射到進程的地址空間,返回指向地址空間的指針

int munmap(void *start, size_t length); //解除地址映射

int shm_unlink(const char *name); //刪除shm_open()建立的共享內存

函數具體用法,可見連接,講述的很詳細了;

 

具體思路:

一:實現進程間的通訊,無非就是各進程間數據的交流,傳輸;

一、shm_open()函數是建立或打開一個已存在(惟一的name)的共享內存,返回文件描述符,能夠看做是建立或打開了一個文件,說法不一樣而已

二、ftruncate()函數用於指定文件(fd)有多大

三、關鍵步驟就是mmap(),它將指定的文件(fd)或其餘對象映射到內存, 獲得能夠直接操做的指針對象,不需調用write, read等

 四、而後就是在使用完成後須要解除映射munmap(), 和刪除建立的共享內存(name)shm_unlink(),; 對於作打開共享內存操做的進程,也須要執行這些操做(1,2,3,4)

 

二:而後使用信號量實現互斥:

互斥的意思爲:當一個進程在臨界區訪問共享資源時,其餘進程不能進入該臨界區訪問任何共享資源

臨界區表明進程將訪問共享資源的一段代碼

當咱們在向共享區寫入數據時,顯然不想多個進程同時訪問,由於會形成沒必要要的麻煩,就須要信號量來實現這種互斥的機制

 

sem_t *sem_open(const char *name,int oflag, mode_t mode,unsigned int value)  //建立或打開一個存在的(name)信號量

int sem_wait(sem_t *sem) // 使信號量(value)減1,若信號量小於0,則阻塞執行semwait()的進程

臨界區代碼通常存在於這兩個調用之間,好比:當前進程向共享區寫數據,如受到sem_wait阻塞,表示資源已經用盡或其餘進程正在訪問,需等待

int sem_post(sem_t *sem) // 當前進程離開臨界區時,使信號量(value)加1,

int sem_unlink(count char *name) //刪除信號量

函數具體用法,可見連接,講述的很詳細了;

 代碼在這裏

 

須要注意的是:

1:在使用共享內存和信號量時要注意,有些調用是使用的共享內存和信號量的name, 但有些是使用的建立或打開他們的返回值(fd和sem_t*)

2:如在子進程建立以前,父進程已建立了共享內存或信號量,則子進程無需在進行打開操做,可直接使用

相關文章
相關標籤/搜索