linux学习之十九---有名管道

有名管道

管道的一个不足之处是没有名字,因此,只能用于具有 亲缘关系的进程间通信,在有名管道提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存储与文件系统中。有名管道是一个设备文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。值得注意的是,FIFO总是按照先进先出的原则工作,第一个被写入的数据将首先从管道中读出。

1.有名管道的创建与读写

Linux下有两种方式创建有名管道。一是在Shell下交互地建立一个有名管道,二是在程序中使用系统函数建立有名管道。

创建有名管道的系统函数有两个:mknod和mkfifo。两个函数均定义在头文件sys/stat.h,函数原型如下:

#include<sys/types.h>
#include<sys/stat.h>
int mknod(const char *path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mode);

mknod&mkfifo函数参数:

path:有名管道的全路径名;
mod:有名管道的模式,指明其存取权限;
dev为设备值,该值取决于文件创建的种类,它只在创建设备文件时才会用到。

返回:这两个函数调用成功都返回0,失败都返回-1。

参数值:

“S_IFIFO|0666”指明创建一个有名管道且存取权限为0666,即创建者、与创建者同组的用户、其他用户对该有名管道的访问权限都是可读可写。

使用有名管道时,必须先调用open()将其打开。调用open()打开有名管道的进程可能会被阻塞,但如果同时用读写方式(O_RDWR)打开,则一定不会导致阻塞;如果以只读方式(O_RDONLY)打开,则调用open()函数的进程将会被阻塞直到有写方打开管道;同样以写方式(O_WRONLY)打开也会阻塞直到有读方打开管道。

2.示例代码:

使用有名管道在两个无亲缘进程之间通信

procwrite.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 1024
 
int main()
{
    int fd;
    char buf[BUF_SIZE]="Hello procwrite,I come from process named procread!";
    
    umask(0);
    if(mkfifo(FIFO_NAME,S_IFIFO|0666)==-1)
    {
       perror("mkfifo error!");
       exit(1);
    }
    if((fd=open(FIFO_NAME,O_WRONLY))==-1)
    {
       perror("fopen error!");
       exit(1);
    }
    write(fd,buf,strlen(buf)+1);
    close(fd);
    exit(0);
}
procread.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 1024

int main()
{
    int fd;
    char buf[BUF_SIZE];
    
    umask(0);
    fd=open(FIFO_NAME,O_RDONLY);
    read(fd,buf,BUF_SIZE);
    printf("Read content:%s\n",buf);
    close(fd);
    exit(0);
}

运行结果:

1.先运行procwrite,

pc@ubuntu:~/linux_lan/pipe/10.3$ ./procwrite

再运行procread,

pc@ubuntu:~/linux_lan/pipe/10.3$ ./procread

在procread端得到:
Read content:Hello procwrite,I come from process named procread!

在两个源程序目录下,出现myfifo文件。

PS:再次运行需删除myfifo。

你可能感兴趣的:(多线程,linux,mkfifo,有名管道,门口)