歡迎您光臨本站 註冊首頁

C語言實現進程間通信原理解析

←手機掃碼閱讀     lousu-xi @ 2020-06-16 , reply:0

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

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()創建的共享內存

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

具體思路:

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

1、shm_open()函數是創建或打開一個已存在(唯一的name)的共享內存,返回文件描述符,可以看作是創建或打開了一個文件,說法不同而已

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

3、關鍵步驟就是mmap(),它將指定的文件(fd)或其他對象映射到內存, 得到可以直接操作的指針對象,不需調用write, read等

4、然後就是在使用完成後需要解除映射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:如在子進程創建之前,父進程已創建了共享內存或信號量,則子進程無需在進行打開操作,可直接使用

                                                       

   


[lousu-xi ] C語言實現進程間通信原理解析已經有314次圍觀

http://coctec.com/docs/c/language/show-post-238754.html