管道是UNIX系統最古老的的程序間通信方式(基本不再使用),曆史上的管道通常是半雙工(隻允許單項資料流動),現在的系統大都可以全雙工(資料可以雙向流動)
管道可分為無名管道和有名管道兩種;接下來将用代碼的形式介紹兩種管道實作程序間的通信。
一、 有名管道
指令:mkfifo
函數:
#include <sys/types.h>
#include <sys/stat.h>
Int mkfifo(const char *pathname, mode_t mode);
功能:建立管道檔案
pathname:檔案路徑
mode:權限
傳回值:成功傳回0,失敗傳回-1
***程式設計模型***
程序A 程序B
建立管道(mkfifo) ...
打開管道(open) 打開管道
讀/寫管道(read/write) 讀/寫資料
關閉管道(close) 關閉管道
删除管道(unlink) ...
有名管道程序A的實作代碼:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
//1.打開管道檔案
int fd = open("/tmp/fifo",O_RDONLY);
if(0 > fd)
{
perror("open");
return -1;
}
//2.讀資料
while(1)
{
char buf[1024] = {};
read(fd,buf,sizeof(buf));
if(0 == strcmp(buf,"quit"))
{
printf("退出\n");
break;
}
printf("read:%s\n",buf);
}
//關閉管道檔案
close(fd);
return 0;
}
有名管道程序B的實作代碼
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
//1.建立管道檔案,一般儲存在/tmp目錄下
if(mkfifo("/tmp/fifo",0644))
{
perror("mkfifo");
return -1;
}
//2.打開管道
int fd = open("/tmp/fifo",O_WRONLY);
if(0 > fd)
{
perror("open");
return -1;
}
//3.寫資料
char buf[1024] = {};
while(1)
{
printf(">");
gets(buf);
write(fd,buf,strlen(buf)+1);
if(0 == strcmp(buf,"quit"))
{
printf("通信完成\n");
break;
}
}
//關閉管道檔案
close(fd);
return 0;
}
二、無名管道
無名管道(用于通過fork建立的父子程序之間通信)
#include <unistd.h>
int pipe(int pipefd[2]);
功能:建立無名管道
pipefd:用來存儲核心傳回的檔案描述
pipefd[0] 用于讀操作
pipefd[1] 用于寫操作
無名管道的實作代碼
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
//建立管道
int pipefd[2] = {};
//打開無名官道
if(pipe(pipefd))
{
perror("pipe");
return -1;
}
//建立程序,父程序寫關閉讀
if(fork())
{
close(pipefd[0]);
printf("父程序:%u\n",getpid());
while(1)
{
char buf[1024] = {};
usleep(1000);
printf(">");
gets(buf);
write(pipefd[1],buf,strlen(buf)+1);
if(0 == strcmp(buf,"quit"))
{
printf("通信結束\n");
close(pipefd[1]);
return 0;
}
}
}
else//子程序讀,關閉寫
{
close(pipefd[1]);
printf("子程序:%u\n",getpid());
while(1)
{
char buf[1024] = {};
read(pipefd[0],buf,sizeof(buf));
if(0 == strcmp(buf,"quit"))
{
printf("通信結束\n");
close(pipefd[0]);
return 0;
}
printf("read:%s\n",buf);
}
}
return 0;
}