溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

常見的Linux進(jìn)程通信方法是什么

發(fā)布時(shí)間:2022-01-26 10:54:02 來源:億速云 閱讀:228 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章主要為大家分析了常見的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

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)站!

向AI問一下細(xì)節(jié)

免責(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)容。

AI