进程间通信之有名管道

通过命令mkfifo +管道名 (创建有名管道文件)

有名管道的使用

1.同时具备读与写的两端都需要打开管道文件才使用有名管道,如只有一方,则打开时阻塞

2.所有有名管道内保存的数据都与管道文件无关,管道文件只提供操作管道的方式


有名管道的几种情况:

读管道:

1.默认情况下操作都是阻塞的(以下几条的前提)

2.写端打开管道,管道无数据,读端读阻塞

3.造成阻塞的两种原因:

            1.管道内有数据,但是其他进程正在读取

            2.管道内无数据,读进程阻塞

4.一个进程多个读端,只有第一个进程读端阻塞,其他读端不阻塞(多线程)

写管道:

1.默认情况下操作都是阻塞的(以下几条的前提)

2.写端向管道内写入数据,内核帮助写端保证数据的原子性判断

        1.写的数据大于4096,不保证数据的原子性

        2。写的数据小于4096,保证数据原子性

注:写端写2000字节后,还想在写3000,这是内存不够大,则处于写阻塞状态,直到内核缓冲去可以存放3000的数据才进行写入

3.非阻塞写管道,如果管道内的剩余空间小于要写入的数据量,返回-1 errno==ESDAIN


代码例子

读端:

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

int main(int argc , char ** argv)
{
	if(argc < 2)
	{
		printf("fifo name....\n");
		exit(0);
	}
	int fd,len;
	char buf[1];
	fd = open(argv[1],O_RDONLY);
	len = read(fd,buf,sizeof(buf));
	printf("read.c recv:\n");
	write(STDOUT_FILENO,buf,len);
	sleep(10);
	close(fd);
	return 0;
}

写端:

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

#define	MSG "testMessage..."
int main(int argc , char ** argv)
{
	if(argc < 2)
	{
		printf("fifo name....\n");
		exit(0);
	}
	int fd;
	mkfifo(argv[1],0664);
	//使用有名管道时,如果没有读端存在,写端尝试打开管道文件阻塞
	//如果一个进程以写方式打开管道,当前没有人以读方式打开管道,写打开阻塞
	fd = open(argv[1],O_WRONLY);
	printf("test...\n");
	write(fd,MSG,strlen(MSG));
	close(fd);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/aaa_cainiao_66666/article/details/80725428
今日推荐