亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > linux系統(tǒng)中管道的介紹和線程同步代碼示例

linux系統(tǒng)中管道的介紹和線程同步代碼示例 時(shí)間:2018-09-26      來源:未知

傳統(tǒng)的進(jìn)程間通信其中有無名管道(PIPE)、有名管道(FIFO)和信號(hào)(Signal)。咱們今天就說說linux中基于POSIX的有名管道(FIFO)和無名管道(PIPE)。

1. 描述:

管道提供一個(gè)單向的進(jìn)程間通訊通道。一個(gè)管道,有一個(gè)讀端和一個(gè)寫端。寫到寫端的數(shù)據(jù)能從這個(gè)管道的讀端讀出。

無名管道,在linux中可以通過pipe2函數(shù)來創(chuàng)建一個(gè)無名管道,執(zhí)行這個(gè)函數(shù)后,會(huì)返回兩個(gè)文件描述符,一個(gè)指向管道的讀端,一個(gè)指向管道的寫端。無名管道用于有親緣關(guān)系的進(jìn)程之間通信。通信方式類似半雙工通信方式。

有名管道(先進(jìn)先出的縮寫),在linux文件系統(tǒng)內(nèi)有一個(gè)名字(區(qū)別無名管道),可以通過mkfifo函數(shù)來創(chuàng)建一個(gè)有名管道。任何進(jìn)程都可以通過open函數(shù)來打開一個(gè)有名管道文件,前提是這個(gè)進(jìn)程有打開權(quán)限。讀端使用open函數(shù)打開的標(biāo)識(shí)是O_RDONLY;寫端在open函數(shù)中使用O_WRONLY來打開。用于任何進(jìn)程之間的通信。

注意:

0)盡管一個(gè)有名管道在文件系統(tǒng)中有一個(gè)名字,但是對(duì)于隱藏設(shè)備,管道的I/O操作不起作用。

1)有名管道和無名管道的不同就在他們的創(chuàng)建和打開的方式上。一旦創(chuàng)建和打開任務(wù)已經(jīng)完成,那么有名管道和無名管道的I/O操作意義完全相同。

2)管道提供的通訊通道是字節(jié)流:沒有消息邊界的概念。

3)不能使用lseek函數(shù)來操作管道。

4)在使用fork創(chuàng)建子進(jìn)程的時(shí)候,要注意適當(dāng)合理的使用close關(guān)閉子進(jìn)程從父進(jìn)程繼承拷貝的多余的讀端或者是寫端的文件描述符。

5)管道中的數(shù)據(jù)從讀端讀走了,就從管道中消失了。

2. 規(guī)則:

1. 讀(讀端寫端都存在):如果一個(gè)進(jìn)程讀一個(gè)空管道,read函數(shù)會(huì)阻塞,直到管道中有可用數(shù)據(jù)。

2. 寫(讀端寫端都存在):如果一個(gè)進(jìn)程想寫一個(gè)已滿管道,write函數(shù)會(huì)阻塞,直到管道中有足夠的數(shù)據(jù)被讀出來讓write函數(shù)完成寫操作。

如果想讓讀寫不阻塞,可以參考fcntl函數(shù)。使用F_SETFL和O_NONBLOCK來完成。

3. 讀(寫端全部關(guān)閉):如果指向?qū)懚说乃形募枋龇急魂P(guān)閉,read函數(shù)對(duì)該管道讀的嘗試結(jié)果會(huì)返回0;

4. 寫(讀端全部關(guān)閉):如果指向讀端的所有文件描述符都被關(guān)閉,write函數(shù)對(duì)該管道的寫操作會(huì)產(chǎn)生SIGPIPE信號(hào),并發(fā)送給調(diào)用write函數(shù)的進(jìn)程;如果調(diào)用write的進(jìn)程忽略了SIFPIPE信號(hào),那write會(huì)帶著EPIPE的錯(cuò)誤而失敗。

管道中的數(shù)據(jù)可讀性只有一次。也就是說數(shù)據(jù)在管道中閱后即焚。管道中的數(shù)據(jù)讀了就沒有了。

(1) 無名管道:int pipe(int pipefd[2]);

參數(shù):

//pipefd 獲得操作管道的文件描述符 ,讀:pipefd[0],寫:pipefd[1]。

返回值: 成功返回0,失敗返回-1

(2)創(chuàng)建有名管道文件

int mkfifo(const char *pathname, mode_t mode);

@pathname 管道文件名

@mode 指定文件的權(quán)限

返回值:

成功返回0,失敗返回-1

下面以兩個(gè)線程中使用有名管道的同步通信為例,展示相關(guān)代碼的使用:

#include

#include

//strlen memset

#include

//mkfifo open

#include

#include

//open

#include

//read

#include

//errno

#include

//pthrea_mutex_unlock

#include

//sem_init sem_wait sem_post

#include

#define N 1024//緩存buf的大小

sem_t read_sem;//讀信號(hào)資源

sem_t write_sem;//寫信號(hào)資源

void *read_fifo(void* args){//讀管道線程的線程主體

int ret = -1;

int fd_r = -1;

char buf[N] = {0};

ssize_t num = 0;

ret = mkfifo((char*)args,0666);

if(ret < 0 && errno != EEXIST){

perror("read_fifo mkfifo failed");

return (char*)args;

}

fd_r = open((char*)args,O_RDONLY|O_NONBLOCK,0666);/*非阻塞方式打開文件獲取文件描述符*/

if(fd_r < 0){

perror("read_fifo open failed");

return (char*)args;

}

while(1)

{

sem_wait(&read_sem);/*讀管道線程獲取讀管道的資源,實(shí)現(xiàn)和寫線程的同步*/

memset(buf,0,sizeof(buf));/*清空緩沖區(qū)*/

num = read(fd_r,buf,sizeof(buf));

buf[N-1] = '\0';/*輸出前的防止越界操作*/

if(num > 0){

printf("%d read:%s\n",num,buf);

}

if(strncmp(buf,"q",1) == 0){/*對(duì)退出字符串的捕捉*/

close(fd_r);

sem_post(&write_sem);

break;

}

sem_post(&write_sem);/*釋放寫操作資源*/

}

close(fd_r);

return (char*)args;

}

void *write_fifo(void* args){

int ret = -1;

int fd_w = -1;

char buf[N] = {0};

ssize_t num = 0;

ret = mkfifo((char*)args,0666);

if(ret < 0 && errno != EEXIST){//排除已經(jīng)創(chuàng)建管道的錯(cuò)誤退出情況

perror("read_fifo mkfifo failed");

return (char*)args;

}

fd_w = open((char*)args,O_WRONLY|O_NONBLOCK,0666);

if(fd_w < 0){

perror("read_fifo open failed");

return (char*)args;

}

while(1)

{

sem_wait(&write_sem);

printf("#:");/*輸入提示符*/

fgets(buf,sizeof(buf),stdin);

buf[strlen(buf) - 1] = '\0';/*對(duì)fgets獲取到終端的’\n’字符的消除*/

num = write(fd_w,buf,strlen(buf));

if(strncmp(buf,"q",1) == 0){

close(fd_w);

sem_post(&read_sem);

break;

}

sem_post(&read_sem);

}

close(fd_w);

return (char*)args;

}

int main(int argc, const char *argv[])

{

int ret_p = -1;

pthread_t tid[2] = {0};

sem_init(&read_sem,0,0);/*程序啟動(dòng)時(shí),管道沒有資源,故讀的資源要初始化為0*/

sem_init(&write_sem,0,1);/*程序啟動(dòng)時(shí),管道首先需要一個(gè)寫操作,故寫資源為1*/

if(argc < 2){/*程序運(yùn)行時(shí),緊跟其后的輸入?yún)?shù)判斷*/

perror("Input wrong format");

puts("Excuting_code_name + new_fifoname");

exit(EXIT_SUCCESS);

}

ret_p = pthread_create(&tid[0],NULL,read_fifo,(char*)argv[1]);/*把在程序后的參數(shù)傳遞給相關(guān)進(jìn)程作為有名管道文件的文件名*/

if(ret_p < 0){

perror("read_fifo pthread_create failed");

exit(EXIT_FAILURE);

}

#if 1

ret_p = pthread_create(&tid[1],NULL,write_fifo,(char*)argv[1]);

if(ret_p < 0){

perror("write_fifo pthread_create failed");

exit(EXIT_FAILURE);

}

#endif

pthread_join(tid[0],NULL);/*線程的阻塞回收,亦可以防止主進(jìn)程結(jié)束*/

pthread_join(tid[1],NULL);

return 0;

}

上一篇:用meteor快速實(shí)現(xiàn)跨平臺(tái)應(yīng)用

下一篇:我們聊聊UI

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部

主站蜘蛛池模板: 欧美视频在线观看免费精品欧美视频 | 久久久亚洲欧洲日产国码二区 | 亚洲精品成人av在线 | 久久99青青久久99久久 | 亚洲永久中文字幕在线 | 人人揉人人捏人人添 | 欧美有色 | 亚洲一区二区三区视频 | 成人综合婷婷国产精品久久免费 | 99精品视频在线观看 | 国内精品福利在线视频 | 国产区视频在线观看 | 欧洲第一页| 秋霞网韩国理伦片不卡免费看 | 午夜在线亚洲男人午在线 | 两个人日本www免费版 | 欧美一区二区三区不卡视频 | 免费福利在线播放 | 国产成人影视 | 亚洲jizzjizz中文在线播放 | 青青青草影院 | 国产精品1页 | 漂亮的保姆在线看韩剧 | 欧美精品一区二区三区久久 | 免费中国jlzzjlzz在线播放 | 成人午夜精品久久不卡 | 日本又黄又爽又免费 | 人人上人人| 欧美成人四级剧情在线播放 | 九草在线视频 | 激情欧美一区二区三区中文字幕 | 天天干天天插 | 91久久国产青草亚洲 | 精品九九九 | 在线播放69热精品视频 | 欧美日韩国产一区二区三区播放 | 操碰在线| 日本肉肉视频免费观看 | 免费观看视频在线 | 欧美视频网站免费看 | 另类老妇性bbwbbw |