C++ 进阶 day11 多进程编程

有名管道

  • 有名字的管道,会在文件系统中创建一个真实存在的管道文件
  • 及可以完成亲缘进程通信,也可以完成非亲缘进程间通信
  • 有名管道的API
    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
  • 功能:创建一个管道文件,并存在于文件系统中
  • 参数1:名称
  • 参数2:权限
  • 返回值:成功返回0,失败返回1并位置错误码
    注意:管道文件被创建后,其他进程就可以进行打开读写操作了,但是,必须要保证当前管道文件的两端都打开后,才能进行读写操作,否则函数会在open处阻塞

案例:

点击查看代码
//create.cpp
#include <myhead.h>
int main(){
	//该文件主要负责创建管道文件,如果文件已经存在那么mkfifo函数会报错
	if(mkfifo("./myfifo",0664)==-1){
		perror("mkfifo error");
		return -1;
	}
	printf("管道创建成功\n");
	return 0;
}
//send.cpp
#include <myhead.h>
int main(){
	//打开管道文件
	int sfd = -1;//文件描述符
	if((sfd = open("./myfifo",O_WRONLY))==-1){
		perror("open error");
		return -1;
	}

	//准备写入的数据
	char wbuf[128]="";
	while(1){
		printf("请输入>>>");
		fgets(wbuf,sizeof(wbuf),stdin);
		wbuf[strlen(wbuf)-1]=0;

		write(sfd,wbuf,strlen(wbuf));
		if(strcmp(wbuf,"quit")==0){
			break;
		}
	}
	close(sfd);

	return 0;
}
//recv.cpp
#include <myhead.h>
int main(){
	//打开管道文件
	int rfd=-1;
	if((rfd=open("./myfifo",O_RDONLY))==-1){
		perror("open error");
		return -1;
	}

	char rbuf[128]="";
	while(1){
		//将容器清空
		bzero(rbuf,sizeof(rbuf));
		//从管道文件中读取数据
		read(rfd,rbuf,sizeof(rbuf));
		printf("收到数据为:%s\n",rbuf);

		if(strcmp(rbuf,"quit")==0){
			break;
		}
	}
	
	close(rfd);
}
* 使用有名管道实现,两个进程之间相互通信,提示:可以使用多进程或多线程
点击查看代码
//create.cpp
#include <myhead.h>
int main(){
	if(mkfifo("./myfifo1",0664)==-1){
		perror("mkfifo error");
		return -1;
	}
	printf("管道1创建成功");

	if(mkfifo("./myfifo2",0664)==-1){
		perror("mkfifo error");
		return -1;
	}
	printf("管道2创建成功");
	return 0;
}
//send.cpp
#include <myhead.h>
int main(){
	pid_t pid=-1;
	pid=fork();
	if(pid>0){
		//父进程代码
		int sfd=-1;
		if((sfd=open("./myfifo1",O_WRONLY))==-1){
			perror("open error");
			return -1;
		}

		char wbuf[128]="";
		while(1){
			printf("请输入<<<\n");
			fgets(wbuf,sizeof(wbuf),stdin);
			wbuf[strlen(wbuf)-1]=0;

			write(sfd,wbuf,sizeof(wbuf));
			if(strcmp(wbuf,"quit")==0){
				break;
			}
		}

		wait(NULL);
	}
	else if(pid==0){
		int rfd=-1;
		if((rfd=open("./myfifo2",O_RDONLY))==-1){
			perror("open error");
			return -1;
		}

		char rbuf[128];
		while(1){
			bzero(rbuf,sizeof(rbuf));
			read(rfd,rbuf,sizeof(rbuf));
			printf("收到数据为:%s\n",rbuf);

			if(strcmp(rbuf,"quit")==0){
				break;
			}
		}
		exit(EXIT_SUCCESS);
	}
	else{
		perror("fork error");
		return -1;
	}
	return 0;
}
//recv.cpp
#include <myhead.h>
int main(){
	pid_t pid=-1;
	pid=fork();
	if(pid>0){
		int rfd=-1;
		if((rfd=open("./myfifo1",O_RDONLY))==-1){
			perror("open error");
			return -1;
		}

		char rbuf[128];
		while(1){
			bzero(rbuf,sizeof(rbuf));
			read(rfd,rbuf,sizeof(rbuf));
			printf("收到数据为:%s\n",rbuf);

			if(strcmp(rbuf,"quit")==0){
				break;
			}
		}
		wait(NULL);
	}
	else if(pid==0){
		int sfd=-1;
		if((sfd=open("./myfifo2",O_WRONLY))==-1){
			perror("open error");
			return -1;
		}

		char wbuf[128]="";
		while(1){
			printf("请输入<<<\n");
			fgets(wbuf,sizeof(wbuf),stdin);
			wbuf[strlen(wbuf)-1]=0;

			write(sfd,wbuf,sizeof(wbuf));
			if(strcmp(wbuf,"quit")==0){
				break;
			}
		}
		exit(EXIT_SUCCESS);
	}
	else{
		perror("fork error");
		return -1;
	}
	return 0;
}
# 总结 信号可以完成多个进程间通知作用,但是,不能进行数据传输功能
posted @ 2025-05-10 22:41  北燃  阅读(27)  评论(0)    收藏  举报