一、有名管道
管道没有名字,因此它们只能用于有一个公共祖先各个进程之间的通信,我们无法在无亲缘关系的进程之间进程IPC通信。
有名管道即FIFO,指先进先出,它是一个半双工的数据流,不同于管道的是每一个FIFO有一个路径名与之关联,从而允许无
亲缘之间的进程进行通信。
二、创建的函数
FIFO由mkfifo函数创建:int mkfifo(const char *pathname,mode_t mode);
其中pathname是一个普通的路径名,它是该FIFO的名字。
mode参数指定文件的权限位,类似于open 第三个参数。
在创建出一个FIFO后,它必须打开来读,或者打开来写,所用的可以是open函数也可以是某个标准的I/O打开函数
三、注意事项
如果当前尚没有任何进程写打开某个FIFO,那么读打开该FIFO的进程将阻塞;
如果当前尚没有任何进程读打开某个FIFO,那么写打开该FIFO的进程将阻塞;
四、例子:
启动两个不同的进程通过两个有名管道进程通信
fifo_server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#define MAXLINE 1024
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void Perror(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}
void server(int readfd,int writefd)
{
int i = 0;
for (i;i < 3;i++)
{
char buf[MAXLINE] = {0};
sprintf(buf,"hello world %d",i);
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#define MAXLINE 1024
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void Perror(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}
void server(int readfd,int writefd)
{
int i = 0;
for (i;i < 3;i++)
{
char buf[MAXLINE] = {0};
sprintf(buf,"hello world %d",i);
int n = write(writefd,buf,strlen(buf));
sleep(1);
}
char buf[MAXLINE] = {0};
int n = read(readfd,buf,MAXLINE);
if (n > 0)
printf("read from client:%s\n",buf);
}
int main()
{
int readfd,writefd;
if ((mkfifo(FIFO1,0777) < 0) && (errno != EEXIST))
Perror("can't create FIFO1");
if ((mkfifo(FIFO2,0777) < 0) && (errno != EEXIST))
{
unlink(FIFO1);
Perror("can't create FIFO2");
sleep(1);
}
char buf[MAXLINE] = {0};
int n = read(readfd,buf,MAXLINE);
if (n > 0)
printf("read from client:%s\n",buf);
}
int main()
{
int readfd,writefd;
if ((mkfifo(FIFO1,0777) < 0) && (errno != EEXIST))
Perror("can't create FIFO1");
if ((mkfifo(FIFO2,0777) < 0) && (errno != EEXIST))
{
unlink(FIFO1);
Perror("can't create FIFO2");
}
printf("create fifo success\n");
readfd = open(FIFO2,O_RDONLY,0);
writefd = open(FIFO1,O_WRONLY,0);
printf("open fifo success\n");
unlink(FIFO1);
unlink(FIFO2);
server(readfd,writefd);
return 0;
}
readfd = open(FIFO2,O_RDONLY,0);
writefd = open(FIFO1,O_WRONLY,0);
printf("open fifo success\n");
unlink(FIFO1);
unlink(FIFO2);
server(readfd,writefd);
return 0;
}
fifo_client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#define MAXLINE 1024
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void Perror(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}
void client(int readfd,int writefd)
{
int i = 0;
for (i;i<3;i++)
{
char buf[MAXLINE] = {0};
int n = read(readfd,buf,MAXLINE);
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#define MAXLINE 1024
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void Perror(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}
void client(int readfd,int writefd)
{
int i = 0;
for (i;i<3;i++)
{
char buf[MAXLINE] = {0};
int n = read(readfd,buf,MAXLINE);
if (n > 0)
printf("read from server :%s\n",buf);
}
char *buf = "goodby server";
write(writefd,buf,strlen(buf));
}
int main()
{
int readfd,writefd;
if ((mkfifo(FIFO1,0777) < 0) && (errno != EEXIST))
Perror("can't create FIFO1");
if ((mkfifo(FIFO2,0777) < 0) && (errno != EEXIST))
{
unlink(FIFO1);
printf("can't create FIFO2");
}
writefd = open(FIFO2,O_WRONLY);
readfd = open(FIFO1,O_RDONLY);
client(readfd,writefd);
printf("read from server :%s\n",buf);
}
char *buf = "goodby server";
write(writefd,buf,strlen(buf));
}
int main()
{
int readfd,writefd;
if ((mkfifo(FIFO1,0777) < 0) && (errno != EEXIST))
Perror("can't create FIFO1");
if ((mkfifo(FIFO2,0777) < 0) && (errno != EEXIST))
{
unlink(FIFO1);
printf("can't create FIFO2");
}
writefd = open(FIFO2,O_WRONLY);
readfd = open(FIFO1,O_RDONLY);
client(readfd,writefd);
return 0
}
}