进程通信之管道

进程通信方式

1.管道
2.共享内存
3.消息队列
4.信号量
5.网络套接字

管道

pipe(无名管道),通常用于父子间沟通操作

#include 
#include 
#include 
#include 


int main(){
	int pipefd[2];
	if(pipe(pipefd)==-1){//pipe 在内核中打开了两个管道文件
		perror("pipe");
		return -1;
	}
	//pipefd[0] 读   pipefd[1] 写
	pid_t id = fork();
	if(id == -1){
		perror("fork");
		return -1;
	}
	//父子进程读写是不固定得,但是写数据得进程关闭读端,同理读数据关闭写端。
	if(id == 0){	//子进程
		close(pipefd[0]);//关闭读,只允许写
		for(;;){
			char str[128] = {};
			fgets(str,128,stdin);
			ssize_t ret = write(pipefd[1],str,strlen(str));
			if(ret == -1){
				break;	
			}
			if(strcmp(str,"!quit\n")==0){
				break;	
			}
		}
		close(pipefd[1]);
	}else{
		close(pipefd[1]);//关闭写	,只允许读
		for(;;){
			char str[128] = {};
			ssize_t ret = read(pipefd[0],str,128);
			if(ret == -1){
				break;	
			}
			printf("recv:%s",str);
			if(strcmp(str,"!quit\n")==0){
				break;	
			}
		}
		close(pipefd[0]);
	}
	
	return 0;	
}

fifo

有名管道,基于管道文件得通信。

server

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define FIFO1 "/tmp/wfifo" //写
#define FIFO2 "/tmp/rfifo"//读

/*
FIFO1 服务端讲该文件作为写入,那么客户端只能从该文件中读取,不允许客户都向该文件写入
FIFO2 服务端讲该文件作为读取,那么客户端只能向该文件中写入

*/

int main(){
	int ret = mkfifo(FIFO1,0664); //创建管道写
	if(ret == -1){
		perror("mkfifo");
		return -1;
	}
	ret = mkfifo(FIFO2,0664);	//创建管道读
	if(ret == -1){
		perror("mkfifo");
		return -1;
	}
	int wfd = open(FIFO1,O_RDWR|O_NONBLOCK);
	int rfd = open(FIFO2,O_RDWR|O_NONBLOCK);
	if(wfd == -1||rfd == -1){
		perror("open");
		return -1;
	}
	pid_t id;
	id = fork();
	if(id == -1){
		perror("fork");
		close(wfd);
		close(rfd);	
	}
	if(id == 0){
		for(;;){
			char str[128] = {};
			fgets(str,128,stdin);
			if(write(wfd,str,strlen(str))<0){
				break;
			}
		}
	}else{
		for(;;){
			char str[128] = {};
			if(read(rfd,str,128)<0){
				if(errno == EAGAIN){
					continue;	
				}	
				break;
			}else
				printf("recv: %s",str);
		}
	}
	close(rfd);
	close(wfd);
	unlink(FIFO1);
	unlink(FIFO2);
	return 0;	
}

client

#include 
#include 
#include 
#include 
#include 
#include 

#define FIFO1 "/tmp/wfifo" 	
#define FIFO2 "/tmp/rfifo"	


int main(){
	int wfd = open(FIFO2,O_RDWR);
	int rfd = open(FIFO1,O_RDWR);
	if(wfd == -1||rfd == -1){
		perror("open");
		return -1;
	}
	pid_t id;
	id = fork();
	if(id == -1){
		perror("fork");
		close(wfd);
		close(rfd);	
	}
	if(id == 0){
		for(;;){	//子进程发送数据给服务端
			char str[128] = {};
			fgets(str,128,stdin);
			if(write(wfd,str,strlen(str))<=0){
				break;
			}
		}
	}else{
		for(;;){	//父进程则一直读取服务端数据
			char str[128] = {};
			if(read(rfd,str,128)<=0){
				break;	
			}
			printf("recv: %s",str);
		}
	}
	close(rfd);
	close(wfd);
	return 0;	
}

你可能感兴趣的:(linux,进程,进程通信)