进程间通信之管道

    管道是Linux中进程间通信的一种方式,它把一个程序的输出直接连接到另一个程序的输入。

无名管道

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

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

            半双工:指数据可以沿着两个方向传输,但同一时刻一个信道只能允许单方向传送,又称为双向交替通信。

      3.可以看作一种特殊的文件,可以使用普通的read()、write()等函数。但它不是普通的文件,并不属于其他任何文件系统且只存在于内存中。

图例

    

示例

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
	int pipefd[2];
	int pid;
	if (pipe(pipefd) < 0){
		return -1;
	}
	pid = fork();
	if (pid < 0 ){
		return -1;
	}else if (pid == 0){
		//关闭写入端,从管道读取数据
		close(pipefd[1]);
		//将管道读取端重定向到0
		dup2(pipefd[0], 0);
		execl("/usr/bin/wc", "wc", NULL);
	}
	//关闭管道读取端,写入数据
	close(pipefd[0]);
	//将管道重定向至1
	dup2(pipefd[1], 1);
	close(pipefd[1]);
	execl("/bin/ls", "ls","-l", NULL);
	close(1);
	return 0;
}

    1.使用pipe创建无名管道

    2.子进程关闭写端,从fd[0]读取数据

    3.父进程关闭读端,从fd[1]写入数据

    4.父进程执行ls, 将结果交给子进程执行wc命令,将最终结果打印出来

命名管道

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

        2.该管道可以通过路径名指出,且在文件系统中是可见的。在建立管道之后,两个进程可以把它当做普通文件一样进行读写操作,使用更加方便

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

图例

    

示例

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

void test()
{
	printf("test\n");
}

int main(int argc, char *argv[])
{
	int fifofd;
	char buff[1024];
	umask(0);
	if (mkfifo("./test.fifo", 0664) < 0){
		if (errno != EEXIST){
			return -1;
		}
	}

	fifofd = open("./test.fifo", O_RDWR);
	if (fifofd < 0){
		return -1;
	}
	while (1){
		memset(buff, 0x00, 1024);
		read(fifofd, buff, 1024);
		if (strncasecmp(buff, "test", 4) == 0){
			test();
		}
	}
	close(fifofd);
	return 0;
}

    1.mkfifo创建管道

    2.使用open打开管道文件

    3.开始对管道文件进行读写操作

    4.通过外部向管道文件写入数据,来实现在程序内部调用test函数,实现指定功能

猜你喜欢

转载自blog.csdn.net/qq_33408113/article/details/80039215