嵌入式 Linux进程间通信(六)——管道
一、管道
管道是单向的、先进先出的、无结构的、固定大小的字节流。写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞;管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。管道存在于系统内核之中,管道只能用于具有亲缘关系进程间的通信。管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。
#include <unistd.h>
int pipe(int pipefd[2]);
int pipe2(int pipefd[2], int flags);
fd[0]用于读取管道,fd[1]用于写入管道
二、有名管道
有名管道与管道不同,FIFO不是临时的对象,是文件系统中真正的实体,可以用mkfifo命令和mkfifo函数创建。只要有合适的访问权限,进程就可以使用FIFO。有名管道创建后,进程就可以将有名管道当做文件,使用文件IO函数对有名管道进行操作,因此使用有名管道进行通信的进程是不相关的。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
读进程:
int main(int argc,char *argv[])
{
int fd;
char buf[255] = {0};
if((mkfifo("fifo",0777) < 0) && (errno != EEXIST))
{
printf("mkfifo failure\n");
return -1;
}
else
{
fd = open("fifo", O_CREAT|O_RDONLY,0777);
while(1)
{
read(fd, buf,255);
printf("%s\n",buf);
}
}
return 0;
}
写进程:
int main(int argc,char *argv[])
{
int fd;
char buf[] = "hello world\n";
if((mkfifo("fifo",0777) < 0) && (errno != EEXIST))
{
printf("mkfifo failure\n");
return -1;
}
else
{
fd = open("fifo",O_CREAT|O_WRONLY,0777);
while(1)
{
write(fd, buf,strlen(buf));
printf("write sucess\n");
sleep(2);
}
}
return 0;
}