您好,登錄后才能下訂單哦!
這篇文章主要為大家分析了常見的Linux進(jìn)程通信方法是什么的相關(guān)知識點(diǎn),內(nèi)容詳細(xì)易懂,操作細(xì)節(jié)合理,具有一定參考價(jià)值。如果感興趣的話,不妨跟著跟隨小編一起來看看,下面跟著小編一起深入學(xué)習(xí)“常見的Linux進(jìn)程通信方法是什么”的知識吧。
進(jìn)程雖然能夠單獨(dú)的運(yùn)行并且完成一些任務(wù),但是難免會和其他的進(jìn)程進(jìn)行數(shù)據(jù)傳輸或者消息通知,那么Linux系統(tǒng)中進(jìn)程通信的方式有那些?
管道是一種古老的IPC通信形式。它有兩個(gè)特點(diǎn):
半雙工,即不能同時(shí)在兩個(gè)方向上傳輸數(shù)據(jù)。有的系統(tǒng)可能支持全雙工。
只能在父子進(jìn)程間。經(jīng)典的形式就是管道由父進(jìn)程創(chuàng)建,進(jìn)程fork子進(jìn)程之后,就可以在父子進(jìn)程之間使用了。
使用popen函數(shù)和pclose函數(shù)結(jié)合來執(zhí)行系統(tǒng)命令,就用到了管道,它們聲明如下:
FILE *popen(const char *command,const char *type); int pclose(FILE *stream);
system()函數(shù)雖然也能夠執(zhí)行系統(tǒng)命令,但是無法獲取執(zhí)行狀態(tài)碼,而執(zhí)行系統(tǒng)命令本質(zhì)上就需要創(chuàng)建子進(jìn)程來完成,因此利用管道可以很方便的獲取子進(jìn)程的輸出內(nèi)容。本文不詳細(xì)展開。
我們看一個(gè)簡單的使用管道的例子,這里使用了pipe函數(shù)來創(chuàng)建管道:
#include #include #include #define MAX_LEN 128 int main(void) { /*0為讀,1為寫*/ int fd[2] = {0}; //描述符 pid_t pid = 0; char line[MAX_LEN] = {0}; int n = 0; /*創(chuàng)建管道,需要傳入兩個(gè)文件描述符*/ if(pipe(fd) 0) { /*關(guān)閉管道的寫描述符*/ close(fd[1]); /*從管道讀取數(shù)據(jù)*/ n = read(fd[0],line,MAX_LEN); printf("read %d bytes from pipe :%s\n",n,line); } /*子進(jìn)程*/ else { /*關(guān)閉管道的讀描述符*/ close(fd[0]); /*向管道寫入數(shù)據(jù)*/ write(fd[1],"www.yanbinghu.com",sizeof("www.yanbinghu.com")); } return 0; }
在程序中,我們創(chuàng)建了一個(gè)管道,父進(jìn)程關(guān)閉了寫通道,子進(jìn)程關(guān)閉讀通道;子進(jìn)程向管道內(nèi)寫入字符串,而父進(jìn)程從管道中讀取字符串并輸出。
運(yùn)行結(jié)果:
read 18 bytes from pipe :www.yanbinghu.com
FIFO也被稱為命名管道,與管道不同的是,不相關(guān)的進(jìn)程也能夠進(jìn)行數(shù)據(jù)交換。
涉及FIFO操作主要函數(shù)為:
int mkfifo(const char *path, mode_t mode);
而FIFO也常常有以下兩個(gè)用途:
無需創(chuàng)建中間臨時(shí)文件,復(fù)制輸出流
多客戶-服務(wù)進(jìn)程應(yīng)用中,通過FIFO作為匯聚點(diǎn),傳輸客戶進(jìn)程和服務(wù)進(jìn)程之間的數(shù)據(jù)
我們看一個(gè)簡單的例子,寫進(jìn)程代碼如下:
#include #include #include #include #include #include #define FIFO "/tmp/fifo" #define MAX_LEN 128 int main(void) { int writeFd; char line[MAX_LEN] = {0}; if(mkfifo(FIFO,S_IRUSR|S_IWUSR) 它首先創(chuàng)建了一個(gè)FIFO,并且打開后,往里面寫入字符串,然后關(guān)閉退出。讀進(jìn)程代碼如下: #include #include #include #include #include #include #define FIFO "/tmp/fifo" #define MAX_LEN 128 int main(void) { int readFd,n; char line[MAX_LEN] = {0}; /*打開FIFO,這里打開可能失敗,應(yīng)該要對返回值處理*/ readFd = open(FIFO,O_RDONLY,0); /*從FIFO讀取數(shù)據(jù)*/ n = read(readFd,line,MAX_LEN); printf("read %d bytes from pipe :%s\n",n,line); close(readFd); /*刪除FIFO*/ unlink(FIFO); return 0; }
它先打開一個(gè)已知的FIFO,然后從FIFO中讀取數(shù)據(jù)。在一個(gè)終端先運(yùn)行寫進(jìn)程,然后運(yùn)行讀進(jìn)程,結(jié)果如下:
read 18 bytes from pipe :www.yanbinghu.com
我們可以看到,兩個(gè)沒有親緣關(guān)系的進(jìn)程可以通過FIFO進(jìn)行通信。消息隊(duì)列消息隊(duì)列可以認(rèn)為是一個(gè)消息鏈表,存儲在內(nèi)核中,進(jìn)程可以從中讀寫數(shù)據(jù)。與管道和FIFO不同,進(jìn)程可以在沒有另外一個(gè)進(jìn)程等待讀的情況下進(jìn)行寫。另外一方面,管道和FIFO一旦相關(guān)進(jìn)程都關(guān)閉并退出后,里面的數(shù)據(jù)也就沒有了,但是對于消息隊(duì)列,一個(gè)進(jìn)程往消息隊(duì)列中寫入數(shù)據(jù)后退出,另外一個(gè)進(jìn)程仍然可以打開并讀取消息。消息隊(duì)列與后面介紹的UNIX域套接字相比,在速度上沒有多少優(yōu)勢。信號量信號量是一個(gè)計(jì)數(shù)器,它主要用在多個(gè)進(jìn)程需要對共享數(shù)據(jù)進(jìn)行訪問的時(shí)候。考慮這一的情況,不能同時(shí)有兩個(gè)進(jìn)程對同一數(shù)據(jù)進(jìn)行訪問,那么借助信號量就可以完成這樣的事情。它的主要流程如下:檢查控制該資源的信號量如果信號量值大于0,則資源可用,并且將其減1,表示當(dāng)前已被使用如果信號量值為0,則進(jìn)程休眠直至信號量值大于0也就是說,它實(shí)際上是提供了一個(gè)不同進(jìn)程或者進(jìn)程的不同線程之間訪問同步的手段。共享內(nèi)存共享內(nèi)存允許多個(gè)進(jìn)程共享一個(gè)給定的存儲區(qū),由于它們是共享一塊內(nèi)存數(shù)據(jù),因此其速度非???。但是需要另外提供手段來保證共享內(nèi)存的同步訪問,例如它可以用到前面所提到的信號量來實(shí)現(xiàn)訪問同步。UNIX域套接字UNIX域套接字和套接字很相似,但是它有更高的效率,因?yàn)樗恍枰獔?zhí)行協(xié)議處理,例如計(jì)算校驗(yàn)和,發(fā)送確認(rèn)報(bào)文等等,它僅僅復(fù)制數(shù)據(jù)。當(dāng)然,它也只適用于同一臺計(jì)算機(jī)上的進(jìn)程間通信。例如redis服務(wù)配置unixsocket啟動后,通過redis-cli的-s參數(shù)就可以指定UNIX域套接字,連接到redis服務(wù)器。
$ redis-cli -s /tmp/redis.sock
redis /tmp/redis.sock>它會比使用網(wǎng)絡(luò)套接字的速度要快。網(wǎng)絡(luò)套接字這個(gè)不用多說,它利用網(wǎng)絡(luò)進(jìn)行通信,與前面所提到的通信方式不同的是,它能用于不同計(jì)算機(jī)之間的不同進(jìn)程間通信。
關(guān)于“常見的Linux進(jìn)程通信方法是什么”就介紹到這了,更多相關(guān)內(nèi)容可以搜索億速云以前的文章,希望能夠幫助大家答疑解惑,請多多支持億速云網(wǎng)站!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。