文章目錄
一、管道的應用實例-父進程喚醒子進程,子進程執(zhí)行某種任務
二、命名管道
1.創(chuàng)建一個命名管道
2.匿名管道與命名管道的區(qū)別
3.命名管道的打開規(guī)則
4.用命名管道實現(xiàn)server&client通信
一、匿名管道的應用實例-父進程喚醒子進程,子進程執(zhí)行某種任務
后續(xù)將源碼上傳到gitee,上傳后修改鏈接。
二、命名管道
- 管道應用的一個限制就是只能具有共同祖先的進程進行通信
- 如果想讓不相關(guān)的進程交換數(shù)據(jù),可以使用FIFO文件來做,它被稱為命名管道
- 命名管道是一種特殊的文件
1.創(chuàng)建一個命名管道
創(chuàng)建命令:mkfifo filename
創(chuàng)建函數(shù): int mkfifo(const char * filename,mode_t mode);
參數(shù):管道的名字,創(chuàng)建的管道權(quán)限
2.匿名管道與命名管道的區(qū)別
- 匿名管道由pipe函數(shù)創(chuàng)建并打開
- 命名管道由mkfifo函數(shù)創(chuàng)建,打開用open
- FIFO(命名管道)與pipe(匿名管道)之間的區(qū)別在于,他們創(chuàng)建與打開的方式不同,這些工作完成后,他們有相同的語義。
3.命名管道的打開規(guī)則
- 如果是只讀方式打開FIFO
- O_NONBLOCK disable:阻塞直到有相應進程為寫而打開FIFO
- O_NONBLOCK enable:立刻返回成功
- 如果是只寫方式打開FIFO
- O_NONBLOCK disable:阻塞直到有相應進程為讀而打開FIFO
- O_NONBLOCK enable:立刻返回失敗,錯誤碼為ENXIO
4.用命名管道實現(xiàn)server&client通信
實例功能:
1創(chuàng)建管道
2 創(chuàng)建的命名管道可以讓兩個進程通信
3. 進程A 向管道中寫入 進程B從管道中讀取并打印到標準輸出
需求分析:首先需要創(chuàng)建兩個進程,client端和server端,還需要一個common文件來聲明共同的定義和方法,所以創(chuàng)建三個文件client.cc,server.cc,common.hpp。接下來逐個文件分析
1.首先,創(chuàng)建管道,只需要創(chuàng)建一次即可,本次案例在server.cc中創(chuàng)建,client.cc中使用即可
common.hpp
#pragma once
#include<iostream>
#include<string>
#define NUM 1024
const std::string fifoname = "./fifo";
uint32_t mode = 0666;
server.cc
umask = 0; //這個設置不影響系統(tǒng)的umask,只影響此進程的
int n = mkfifo(fifoname.c_str(),mode);
至此管道已經(jīng)創(chuàng)建
2.讓服務端直接開啟管道文件
int rfd = open(fifoname.c_str(),O_RDONLY);
//打開失敗
if(rfd < 0)
{
std::cout<<errno<<endl;
return 2;
}
//打開成功
....
3.client端不需要創(chuàng)建文件,只用寫方式打開文件就可以
// int open(const char * pathname ,int oflag, ...)
//成功則返回文件描述符,失敗-1
int wfd = open(filename.c_str(),O_WRONLY);
if(wfd <0)
{
//寫方式打開失敗
return 1;
}
4.兩端開始通信
server端:
char buffer[1024];
while(true)
{
buffer[0] = 0;
//read(int fd , void * buf, size_t count) fd是文件描述符,用于要定位讀取的文件或者其他設備,buf為緩沖區(qū)地址,count是要讀取的字節(jié)數(shù),讀成功返回實際讀取的字節(jié)數(shù),返回復數(shù)讀取失敗,返回0讀取到文件末尾
//從rfd文件中讀取x個字節(jié)到buffer中
ssize_t n = read(rfd,buffer,sizeof(buffer)-1);
if(n> 0)
{
buffer[n] = 0;
std::cout<<"client " <<buffer <<std::endl;
}
else if(n== 0)
{
std::cout<<"client quit, me too" <<std::endl;
break;
}
else
{
std::cout<<errno<<std::endl;
break;
}
}
client端:
char buffer[NUM];
while(true)
{
std::cout<<"please enter your message : ";
char * msg = fgets(buffer,sizeof(buffer)-1,stdin);
assert(msg);
(void)msg;
//處理發(fā)送消息的回車,最后一個字符刪掉
buffer[strlen(buffer)-1] = o;
ssize_t n = write(wfd,buffer,strlen(buffer));
assert(n>= 0);
(void)n;
}
5.兩端通信結(jié)束,關(guān)閉對應的文件描述符
close(wfd);文章來源:http://www.zghlxwxcb.cn/news/detail-682710.html
close(rfd);文章來源地址http://www.zghlxwxcb.cn/news/detail-682710.html
到了這里,關(guān)于Linux通信--構(gòu)建進程通信的 方案之管道(下)|使用匿名管道實現(xiàn)功能解耦|命名管道實現(xiàn)serve&client通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!