看了个教程,感觉还是要结合代码看。

管道是linux里面进程间通信的一种方式,其他的还有像信号(signal)、信号量、消息队列、共享内存、套接字(socket)等。


1.管道pipe

int pipe( int fd[2] );

返回值:成功,返回0,否则返回-1。参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道,fd[1]:写管道。

必须在fork()中调用pipe(),否则子进程不会继承文件描述符。两个进程不共享祖先进程,就不能使用pipe。但是可以使用命名管道。


#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
	int pipe_fd[2];
	pid_t pid;
	char buf_r[100];
	char* p_wbuf;
	int r_num;
	memset(buf_r,0,sizeof(buf_r));
	if(pipe(pipe_fd)<0)
		{
			printf("pipe create error\n");
			return -1;
		}
	if((pid=fork())==0)
		{
			printf("\n");
			close(pipe_fd[1]);  /*关闭写管道描述符*/
			sleep(2);
			if((r_num=read(pipe_fd[0],buf_r,100))>0){
				printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
			}
			close(pipe_fd[0];
			exit(0);
		}
		else if(pid>0){
			close(pipe_fd[0]);
			if(write(pipe_fd[1],"hello",5)!=-1)
				printf("parent write1 success!\n");
			if(write(pipe_fd[1],"pipe",5)!=-1)
				printf("parent write2 success!\n");
			close(pipe_df[1]);
			sleep(3);
			waitpid(pid,NULL,0);
			exit(0);
		}
} 

2.流管道

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

#define BUFSIZE 1000

int main()
{
	FILE *fp;
	char *cmd = "ps -ef";
	char buf[BUFSIZE];
	buf[BUFSIZE] = '\0';	
	if((fp=popen(cmd,"r"))==NULL)
		perror("popen");
	while((fgets(buf,BUFSIZE,fp))!=NULL)
		printf("%s",buf);
	pclose(fp);
	exit(0);
}



3.命名管道FIFO

特点:1.FIFO是作为一个特殊的设备文件存在;

2.不同祖先进程的进程之间可以共享数据;

3.使用完后FIFO将继续保存。

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"                                         //管道位置

main(int argc,char** argv)
{
	char buf_r[100];
	int  fd;
	int  nread;                                               
	
	if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))       //创建并执行
		printf("cannot create fifoserver\n");
	printf("Preparing for reading bytes...\n");
	
	memset(buf_r,0,sizeof(buf_r));
	fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);                      //readonly 不阻塞
	if(fd==-1)
	{
		perror("open");
		exit(1);	
	}
	while(1)
	{
		memset(buf_r,0,sizeof(buf_r));
		
		if((nread=read(fd,buf_r,100))==-1){                //读取管道
			if(errno==EAGAIN)
				printf("no data yet\n");
		}
		printf("read %s from FIFO\n",buf_r);
		sleep(1);
	}	
	pause();
	unlink(FIFO);
}

通常对命名管道的读在写之前。

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"

main(int argc,char** argv)                               //argc:参数个数?    argv:参数
{
	int fd;
	char w_buf[100];
	int nwrite;
	
	if(fd==-1)
		if(errno==ENXIO)
			printf("open error; no reading process\n");
	fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);                           //writeonly,管道已在read中创建,可以直接打开。
	if(argc==1)
		printf("Please send something\n");
	strcpy(w_buf,argv[1]);
	if((nwrite=write(fd,w_buf,100))==-1)                                  //write
	{
		if(errno==EAGAIN)
			printf("The FIFO has not been read yet.Please try later\n");
	}
	else 
		printf("write %s to the FIFO\n",w_buf);
}

FIFO创建后,可以用open(),close(),read(),write(),unlink()等流操作函数操作。


Logo

更多推荐