linux系统编程:进程间通信-pipe

                            进程间通信-pipe

进程间通信

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。


pipe

管道(pipe)就是一项基本的进程间通信的方法。

#include 
int pipe(int pipefd[2]);
使用pipe函数,就可以构建一条通信管道。

pipefd是传出参数,表示文件描述符。pipefd[0]是管道的读端,pipefd[1]是管道的写端。

成功,返回0;出错,返回-1。

管道的本质是环形队列。

管道的通用使用模式是先pipe。再fork。于是,父子进程都各有了一份管道的读端和写端。这表明父子进程本质上都可以读写管道,但使用中遵循只读只写的习惯:父子进程要么只读,要么只写。

#include 
#include 
#include 
#include 
void sys_err(char *s)
{
	perror(s);
	exit(1);
}
int main(void)
{
	char buf[100];
	int fd[2];
	pid_t pid;
	if (pipe(fd) < 0) sys_err("pipe");
	//get the size of pipe
	printf("pipe size is %ld\n", fpathconf(fd[0], _PC_PIPE_BUF));
	pid = fork();
	if (pid < 0) sys_err("fork");
	else if (0 == pid)
	{
		/* in child */
		close(fd[1]);   //子进程关闭写端
		int n;
		while (1)
		{
			n = read(fd[0], buf, 100);
			write(STDOUT_FILENO, buf, n);
		}
		close(fd[0]);
	}
	else
	{
		/* in parent */
		close(fd[0]);   //父进程关闭读端
		int i = 0;
		while (1)
		{
			sprintf(buf, "zhangxiang %d\n", i++);
			write(fd[1], buf, strlen(buf));
			sleep(1);
		}
		close(fd[1]);
	}
	return 0;
}
pipe size is 4096
zhangxiang 0
zhangxiang 1
zhangxiang 2
zhangxiang 3
zhangxiang 4
zhangxiang 5
^c


通过fpathconf函数可以获取管道的大小(单位:字节)。这个值不是固定的,与系统设置有关。

以上的示例中父进程关闭读端,不断地往管道中写数据,子进程关闭写端,不断地从管道中读数据。这是典型的父子进程通过管道通信的方式。

父进程若是想读,子进程若是想写,则需另开辟一条管道进行通信。



CCPP Blog 目录



你可能感兴趣的:(linux系统编程)