C語言實現程序間通訊原理解析
最近學習了作業系統的併發;以下是關於程序間實現併發,通訊的兩個方法。
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:利用共享記憶體實現通訊, 訊號量實現互斥
共享記憶體使用了以下函式:
intshm_open(const char *name,int oflag,mode_t mode); //建立或開啟共享記憶體, 返回檔案描述符
intftruncate(int fd,off_t FILE_SIZE); //調整共享記憶體空間大小
void*mmap( void * addr,size_t len,int prot,int flags,int fd,off_t offset ) //將檔案對映到程序的地址空間,返回指向地址空間的指標
intmunmap(void *start,size_t length); //解除地址對映
intshm_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,mode_t mode,unsigned int value) //建立或開啟一個存在的(name)訊號量
intsem_wait(sem_t *sem) // 使訊號量(value)減1,若訊號量小於0,則阻塞執行semwait()的程序
臨界區程式碼一般存在於這兩個呼叫之間,比如:當前程序向共享區寫資料,如受到sem_wait阻塞,表示資源已經用盡或其他程序正在訪問,需等待
intsem_post(sem_t *sem) // 當前程序離開臨界區時,使訊號量(value)加1,
intsem_unlink(count char *name) //刪除訊號量
函式具體用法,可見連結,講述的很詳細了;
程式碼
需要注意的是:
1:在使用共享記憶體和訊號量時要注意,有些呼叫是使用的共享記憶體和訊號量的name,但有些是使用的建立或開啟他們的返回值(fd和sem_t*)
2:如在子程序建立之前,父程序已建立了共享記憶體或訊號量,則子程序無需在進行開啟操作,可直接使用
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。