进程间通信:采用有名管道,创建两个发送接收端,父进程写入管道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;
}
相关推荐
A懿轩A28 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神29 分钟前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
云边有个稻草人33 分钟前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
半盏茶香34 分钟前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
冬天vs不冷35 分钟前
Linux用户与权限管理详解
linux·运维·chrome
忘梓.1 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
算法·动态规划
凯子坚持 c1 小时前
深入Linux权限体系:守护系统安全的第一道防线
linux·运维·系统安全
️南城丶北离2 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工2 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++