进程间通信:采用有名管道,创建两个发送接收端,父进程写入管道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;
}
相关推荐
tingting01195 分钟前
Linux 普通用户禁用sudo su - 命令
linux·运维·服务器
WZF-Sang8 分钟前
Linux—进程学习-01
linux·服务器·数据库·学习·操作系统·vim·进程
幼儿园园霸柒柒12 分钟前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
好想有猫猫31 分钟前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
忘梓.37 分钟前
排序的秘密(1)——排序简介以及插入排序
数据结构·c++·算法·排序算法
写代码的学渣1 小时前
Linux云计算个人学习总结(一)
linux·运维·云计算
福大大架构师每日一题1 小时前
文心一言 VS 讯飞星火 VS chatgpt (384)-- 算法导论24.5 4题
算法·文心一言
云卓科技1 小时前
无人车之路径规划篇
人工智能·嵌入式硬件·算法·自动驾驶
别NULL1 小时前
《现代网络技术》读书笔记:SDN数据平面和OpenFlow
linux·网络·平面·sdn
没有名字的小羊1 小时前
二.Linux文件与目录管理
linux·运维·服务器