进程间通信:采用有名管道,创建两个发送接收端,父进程写入管道1和管道2,子进程读取管道2和管道1.

1.无名管道

无名管道是一种特殊的IPC(进程间通信)机制,它可以在Linux系统中用于将一个进程的输出连接到另一个进程的输入。以下是使用无名管道的一般步骤:

  1. 创建管道:

    bash 复制代码
    int pipefd[2];
    pipe(pipefd);

    这将创建一个管道,并返回两个文件描述符。pipefd[0]用于读取管道的数据,pipefd[1]用于写入管道的数据。

  2. 创建子进程:

    bash 复制代码
    pid_t pid = fork();

    fork()系统调用将创建一个子进程,该子进程将继承父进程的文件描述符。

  3. 在子进程中关闭读端或写端:

    bash 复制代码
    if (pid == 0) {
        close(pipefd[0]); //关闭读端(子进程只写入管道)
        // 执行需要发送数据的命令,并将输出写入管道
        write(pipefd[1], data, strlen(data)); 
        close(pipefd[1]); //关闭写端
        exit(0);
    }

    在父进程中关闭读端或写端:

bash 复制代码
if (pid > 0) {
    close(pipefd[1]); //关闭写端(父进程只读取管道数据)
    //从管道读取数据并进行处理
    read(pipefd[0], buffer, sizeof(buffer));
    close(pipefd[0]); //关闭读端
}

等待子进程结束:
5.

bash 复制代码
wait(NULL);

通过以上步骤,你可以在两个进程之间使用无名管道进行通信。注意,在使用管道时需要适当处理文件描述符的关闭,以避免资源泄漏和错误。

2.有名管道

在现代操作系统中,进程间通信(IPC)是一个至关重要的功能,它允许运行在同一台计算机上的不同进程之间进行数据交换。有名管道(FIFO)是实现IPC的一种方式,它提供了一种在不同进程间传输数据的机制。

有名管道与无名管道(PIPE)相比,最大的区别在于它们可以在没有亲缘关系的进程间使用。有名管道通过在文件系统中创建一个特殊的文件来实现,这个文件不占用磁盘空间,但提供了一个路径名,使得任何可以访问该路径的进程都能够通过它来交换数据。

创建有名管道的过程相对简单。在Linux系统中,可以使用`mkfifo`命令或者`mkfifo()`函数来创建管道文件。一旦创建,进程就可以通过标准的文件I/O调用来读写管道,如`open()`, `read()`, `write()`, 和 `close()`。

使用有名管道进行IPC的一个典型场景是,一个进程写入数据到管道,而另一个进程读取管道中的数据。这种方式的通信是单向的,但可以通过创建两个有名管道来实现双向通信。

值得注意的是,有名管道在使用过程中需要考虑同步问题。例如,如果一个进程尝试从空管道中读取数据,它将会被阻塞,直到有数据写入。同样,如果管道已满,写入操作也会被阻塞。此外,当所有写入端关闭后,读取操作将返回0,表示到达了管道的末尾。

有名管道是Linux进程间通信机制中的一个强大工具,它的使用提高了进程间通信的灵活性和效率。通过合理的设计和同步机制,开发者可以利用有名管道在不同进程间高效地传递信息。

使用有名管道需要经过以下几个步骤:

  1. 创建有名管道:使用命令 mkfifo 创建有名管道文件。例如,执行命令 mkfifo mypipe 将创建一个名为 mypipe 的有名管道文件。

  2. 打开管道:在程序中使用 open 函数来打开有名管道,指定相应的管道文件路径和操作模式。例如,使用以下代码片段打开管道:

    int fd = open("mypipe", O_WRONLY);

  3. 写入数据:使用 write 函数将数据写入管道。例如,使用以下代码将数据写入管道:

    char buffer[1024] = "Hello, pipe!";
    write(fd, buffer, strlen(buffer));

  4. 关闭管道:使用 close 函数关闭管道。例如,使用以下代码关闭管道:

    close(fd);

注意:在使用有名管道时,需要保证有读端和写端同时打开。如果没有进程打开管道的读端,写入端将被阻塞,反之亦然。

作业1:有名管道,创建两个发送接收端,父进程写入管道1和管道2,子进程读取管道2和管道1.

右进程

复制代码
#include <myhead.h>
int main(int argc, const char *argv[])
{
	pid_t pid=fork();
	if(pid>0)//父进程,将数据发送至管道1
	{
		int fd1;
		char buff[1024];
		fd1=open("./fifo_a",O_WRONLY);
		if(fd1==-1)
		{
			perror("打开管道1");
			return -1;
		}
		while(1)
		{
			fgets(buff,sizeof(buff),stdin);//从键盘读取数据
			buff[strlen(buff)-1] = '\0';
			write(fd1,buff,sizeof(buff));//将数据发送至管道1
			if(strcmp(buff,"quit")==0)
			{
				break;
			}
		}

		close(fd1);
	}
	else if(pid==0)
	{
		int fd2;

		char buff1[1024];

		fd2=open("./fifo_b",O_RDONLY);
		if(fd2==-1)
		{
			perror("打开管道2");
			return -1;
		}
		while(1)
		{

			read(fd2,buff1,sizeof(buff1));//从管道2读取数据
			
			if(strcmp(buff1,"quit")==0)
			{
				break;
			}
            printf("%s\n",buff);
		}
		close(fd2);
	}
	else
	{
		perror("pid");
		return -1;
	}
	return 0;
}

左进程

复制代码
#include <myhead.h>
int main(int argc, const char *argv[])
{
	pid_t pid=fork();
	if(pid>0)//父进程,将数据发送至管道1
	{
		int fd1;
	
		char buff[1024];
		fd1=open("./fifo_b",O_WRONLY);
		if(fd1==-1)
		{
			perror("打开管道1");
			return -1;
		}
		while(1)
		{
			fgets(buff,sizeof(buff),stdin);//从键盘读取数据
			buff[strlen(buff)-1] = '\0';
			write(fd1,buff,sizeof(buff));//将数据发送至管道1
			if(strcmp(buff,"quit")==0)
			{
				break;
			}
		}

		close(fd1);
	}
	else if(pid==0)
	{
		int fd2;
	
		char buff1[1024];

		fd2=open("./fifo_a",O_RDONLY);
		if(fd2==-1)
		{
			perror("打开管道2");
			return -1;
		}
		while(1)
		{

			read(fd2,buff1,sizeof(buff1));//从管道2读取数据
			
		
			if(strcmp(buff1,"quit")==0)
			{
				break;
			}
             printf("%s\n",buff);
		}
		close(fd2);
	}
	else
	{
		perror("pid");
		return -1;
	}
	return 0;
}
相关推荐
笑口常开xpr2 分钟前
Linux动静态库开发基础:静态库与动态库的编译构建、链接使用及问题排查
linux·c语言·动态库·静态库
艾莉丝努力练剑28 分钟前
【C++】类和对象(下):初始化列表、类型转换、Static、友元、内部类、匿名对象/有名对象、优化
linux·运维·c++·经验分享
风_峰34 分钟前
PuTTY软件访问ZYNQ板卡的Linux系统
linux·服务器·嵌入式硬件·fpga开发
数智顾问40 分钟前
从ENIAC到Linux:计算机技术与商业模式的协同演进——云原生重塑闭源主机,eBPF+WebAssembly 双引擎的“Linux 内核即服务”实践
linux
疋瓞42 分钟前
C++_STL和数据结构《1》_STL、STL_迭代器、c++中的模版、STL_vecto、列表初始化、三个算法、链表
数据结构·c++·算法
JJJJ_iii44 分钟前
【左程云算法09】栈的入门题目-最小栈
java·开发语言·数据结构·算法·时间复杂度
-SGlow-1 小时前
Linux相关概念和易错知识点(45)(网络层、网段划分)
linux·运维·服务器·网络
三体世界1 小时前
测试用例全解析:从入门到精通(1)
linux·c语言·c++·python·功能测试·测试用例·测试覆盖率
过尽漉雪千山1 小时前
Flink1.17.0集群的搭建
java·大数据·linux·flink·centos
Bear on Toilet1 小时前
继承类模板:函数未在模板定义上下文中声明,只能通过实例化上下文中参数相关的查找找到
开发语言·javascript·c++·算法·继承