我是靠谱客的博主 优雅毛巾,最近开发中收集的这篇文章主要介绍【Linux】管道通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

现在Linux进程间通信方式包括:无名管道(pipe)及有名管道(fifo)、信号(signal)、消息队列(message queue)、共享内存(shared memory)、信号量(semaphore)、套接字(socket)

管道:把一个程序的输出直接连接到另一个程序的输入。

无名管道

(1)只能用于具有亲缘关系的进程之间的通信(父进程和子进程之间)

(2)单工通信模式,固定读端和写端

(3)特殊的文件,可以使用普通的read()、write()等函数,不属于文件系统,只存在于系统中

创建与关闭——pipe()、close()

头文件;#include <unistd.h>

函数原型:int pipe(int fd []);

fd:包含两个元素的整型数组,存放管道对于文件描述符

成功:0

失败:-1

创建管道 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int pfd[2];
int ret=pipe(pfd);
if(ret<0)
{
perror("fail to pipe");
exit(-1);
}
}

无名管道是基于文件描述符的通信方式。当一个管道建立时,他会创造两个文件描述符:fd[0]--读端、fd[1]--写端

管道关闭时只需要用close()函数将两个文件描述符关闭

示例:首先创建管道,然后父进程使用fork()函数创建子进程,最后通过关闭父进程的读描述符和子进程的写描述符,建立它们之间的管道通信

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h> //?
#include <sys/wait.h>
#include <string.h>
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main()
{
pid_t pid;
int pipe_fd[2];
char buf[MAX_DATA_LEN];
const char data[]="Pipe Test Program";
int real_read,real_write;
memset(buf,0,sizeof(buf));
if(pipe(pipe_fd[2])<0) //创建管道
{
perror("fail to pipe");
exit(-1);
}
if((pid=fork())==0) //创建子进程
{
close(pipe_fd[1]); //子进程关闭写描述符
sleep(DELAY_TIME); //通过暂停1s等待父程序关闭相应的读描述符
if((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) //子进程读取管道内内容到buf里
{
printf("%d bytes read from the pipe is '%s'n",real_read,buf);
}
close(pipe_fd[0]); //关闭子程序读描写符
exit(0);
}
else if(pid>0)
{
close(pipe_fd[0]); //关闭父进程读描述符
if((real_write=write(pipe_fd[1],data,strlen(data)))!=-1)
{
printf(""parent wrote %d bytes:'%s'n",real_write,data);
}
close(pipe_fd[1]); //关闭父进程写描述符
wait(pid,NULL,0); //收集子进程退出信息
exit(0);
}
}

有名管道

创建管道——mkfifo()

头文件:

#include <sys/types.h>

#include <sys/state.h>

函数原型:int mkfifo(const char *filename, mode_t mode)

filename:要创建的管道名

mode:管道的访问权限

成功:0

失败:-1

创建成功后可以使用open()、read()、write()。对于为读而打开的管道可在open()中设置O_RDONLY,对于为写而打开的管道可在open()中设置O_WRONLY。 

示例:示例包含两个程序,一个用于读管道,另一个用于写管道。在读管道的程序里创建管道,并且作为main()函数里的参数由用户输入要写入的内容。读管道的程序会读出用户写入管道的内容。

写管道:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#define MYFIFO "/tmp/myfifo" //有名管道文件名
int main(int argc,char *argv[])
{
int fd;
int nwrite;
if(argv<2)
{
printf("Usage:./fifo_write stringn");
exit(-1);
}
if((fd=open(MYFIFO,O_WRONLY))<0) //以只写方式打开FIFO管道
{
perror("fail to open fifo");
exit(-1);
}
if((nwrite=write(fd,argv[1],strlen(argv[1])+1))>0) //向管道中写入字符串
{
printf("Write '%s' to FIFOn",argv[1]);
}
close(fd);
return 0;
}

 读管道:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#define MYFIFO "/tmp/myfifo" //有名管道文件名
int main()
{
char buf[256];
int fd;
//判断有名管道是否已存在,若尚未建立,则以相应的权限创建
if(access(MYFIFO,F_OK)==-1) //管道不存在
{
if(mkfifo(MYFIFO,O666)<0)
{
perror("fail to mkfifo");
exit(-1);
}
}
//以只读的方式打开有名管道
if((fd=open(MYFIFO,O_RDONLY))<0)
{
perror("fail to open fifo");
exit(-1);
}
while(1)
{
memset(buf,0,sizeof(buf)); //?
if((nread=read(fd,buf,256))>0)
{
printf("Read '%s' from FIFOn",buf);
}
}
close(fd);
return 0;
}

最后

以上就是优雅毛巾为你收集整理的【Linux】管道通信的全部内容,希望文章能够帮你解决【Linux】管道通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部