进程间通信——无名管道和有名管道

一、无名管道

无名管道是Linux中管道通信的一种原始方法,如图所示

具有以下特点:

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

2.是一个单工的通信模式,具有固定的读端和写端

3.管道也可以看成一种特殊的文件,对于它的读写也可以使用普通的read()、write()等函数。但是它不属于任何文件系统,并且只存在于内核内存中

二、有名管道

有名管道是无名管道的一种改进,如图所示

它具有以下特点:

1.它可以使两个互不相关的进程实现彼此通信

2.该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了有名管道之后,两个进程就可以把它当作普通文件进行读写操作,使用非常方便

3.FIFO严格地遵循先进先出规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加的末尾。有名管道不支持如sleek()等文件定位操作

三、主要函数

 1.无名管道

       #include <unistd.h>

       int pipe(int pipefd[2]);

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <fcntl.h>              /* Obtain O_* constant definitions */
       #include <unistd.h>

       int pipe2(int pipefd[2], int flags);

 2.有名管道

       #include <sys/types.h>
       #include <sys/stat.h>

       int mkfifo(const char *pathname, mode_t mode);

       #include <fcntl.h>           /* Definition of AT_* constants */
       #include <sys/stat.h>

       int mkfifoat(int dirfd, const char *pathname, mode_t mode);

 四、实例

1.无名管道

/*########################################################################
# File Name: unnamed_pipes.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 12时34分01秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)

#define buf_size 128
#include<unistd.h>
char buf1[buf_size] = {0};
char buf2[buf_size] = {0};
ssize_t read_val = 0;
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/wait.h>
#define DELAY_TIME 1

int main(int argc,char **argv){
	int pipefd[2];
	pid_t cpid1;

	/*创建无名管道*/
	if(ERRVAL == pipe(pipefd))
		handle_error("pipe");

	/*创建父子进程*/
	if(ERRVAL == (cpid1 = fork()))
		handle_error("fork");

	if(0 == cpid1){//child1 process
		if(ERRVAL == close(pipefd[0]))//close read pipe
			handle_error("close");
		sleep(DELAY_TIME);
		while(0 < (read_val = read(STDIN_FILENO, &buf1, buf_size)))
			write(pipefd[1], &buf1, read_val);
		if(ERRVAL == close(pipefd[1]))//close write pipe
			handle_error("close");
	}
	else{//father process
		if(ERRVAL == close(pipefd[1]))//close write pipe
			handle_error("close");
		while(0 < (read_val = read(pipefd[0], &buf2, buf_size)))
			write(STDOUT_FILENO, &buf2, read_val);
		putchar(10);
		if(ERRVAL == close(pipefd[0]))//close read pipe
			handle_error("close");
	}
	return 0;
}

 2.有名管道

创建管道:

/*########################################################################
# File Name: mkfifo.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 21时53分27秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)

#include<sys/types.h>
#include<sys/stat.h>
#define _MODE 0644

int main(int argc,char **argv){
	if(ERRVAL == mkfifo("fifo", _MODE)) handle_error("mkfifo");
	else puts("make success!");
	return 0;
}

 

 写端:

/*########################################################################
# File Name: famous_pipe.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 14时57分55秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)

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

int main(int argc,char **argv){
//	if(ERRVAL == mkfifo("./fifo", 0664))handle_error("mkfifo");
	char buf[10] = "hello";
	int fd;
	fd = open("fifo", O_RDWR);
	write(fd, buf, strlen(buf));
	return 0;
}

读端:

/*########################################################################
# File Name: famous_pipe2.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 15时10分05秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)

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

int main(int argc,char **argv){
	int fd;
	if(ERRVAL == (fd = open("fifo", O_RDONLY)))handle_error("open");
	char buf[10];
	read(fd, buf, 10);
	printf("%s\n", buf);
	return 0;
}

效果:

 注意:读写两端程序需要同时运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值