进程通信之---无名管道,pid取值范围

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39956356/article/details/86648643

目录

  • 特点及使用对象
  • 参数的定义
  • 案例
(一)特点及使用对象

(1)伴随unix的产生,无名管道的通信方式就存在,有点类似硬
件中的串口

(2)是种半双工通信方式,即同一时刻只有读进程在读或写进程在写
(3)只有血缘关系的进程才可以通信,如fork创建的子进程
(4)写入管道写端的数据由内核缓冲,直到从读取端读取管道,必须要有读进程,读可以阻塞的

(二)参数的定义
int pipe(int pipefd[2]);

管道有两个文件描述符相当于管道的两端,一端只负责读数据,一端只负责写数据

pipefd[0]:用于读管道

pipefd[1]:用于写管道

上面两句话特别重要!!!
还有个习惯(也是必要的):
操作写端,先关闭读端close(pipes[0]);
操作读端,先关写读端close(pipes[1]);

(三)案例

问题描述:先用fork创建子进程,子进程读,父进程写。
结果:你输入什么,输出什么。
一个一个分析:
在这里插入图片描述
读函数:
在这里插入图片描述
写函数:
在这里插入图片描述
源码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>												//exit(1);头文件


/****************************************************************************************
**									无名管道
** pipe():
**	 int pipe(int pipefd[2]);
** RETURN VALUE
** 	On success, zero is returned.  On error, -1 is returned
** 注意:a unidirectional data channel that can be used for interprocess communication
			一种单向数据通道,只能用于内部进程通信----父子进程间
	pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe.
		pipefd[0]:用于读管道;	参数pipefd[1]:用于写管道
	Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe.
		写入管道写端的数据由内核缓冲,直到从读取端读取管道。
****************************************************************************************/

int pipe(int pipefd[2]);

//读数据--pipe[0]
void read_data(int *);

//写数据--pipe[1]
void write_data(int *);


int main(int argc, char *argv[])
{
	int pipes[2], rc;
	pid_t pid;													//为了调用fork
	
	//新建管道
	rc = pipe(pipes);
	if(rc == -1)
	{
		perror("pipe error!!!\n");
		exit(1);
	}
	
	//创建进程
	pid = fork();
	switch(pid)
	{
		case -1:
			perror("fork error!!!\n");
			exit(1);
		case 0:                          						//子进程,也可以传一个
			read_data(pipes);
		default:												//父进程,也可以传一个
			write_data(pipes);
	}
}



void read_data(int pipes[])
{
	int ret, buffer;
	
	close(pipes[1]);											//关闭写通道
	printf("pipe[0] data: ");
	while((ret = read(pipes[0],&buffer, 1)) > 0)   				//每次读一个数据
	{
		putchar(buffer);
		if(buffer == '\n')
			printf("pipe[0] data: ");							//输出提示
	}
	printf("Read pipes[0] failed!!!\n");
	exit(1);
}


void write_data(int pipes[])
{
	int ret, buffer;
	
	close(pipes[0]);										//关闭读通道
	printf("write pipe[1]: ");
	while((buffer = getchar()) > 0)
	{
		ret = write(pipes[1], &buffer, 1);					//每次写一个数据
		if(ret == -1)
		{
			perror("Write pipes[1] error!!!\n");
			close(pipes[1]);								//关闭写端
			exit(1);
		}
/* 		if(buffer == '\n')
		printf("write pipe[1]: ");							//输出提示 */
	}
	close(pipes[1]);										//关闭写端
	exit(0);
}

**输出:**输入什么,输出什么,ok.
在这里插入图片描述
注: 上面提到了一个pid能否用尽的问题?
其实几乎不可能的,原因如下:

  • (1)pid的最大值PID_MAX=0x8000(可改),因此进程号的最大值为0x7fff,即32767(short int的最大值)
  • (2)pid按照递增加1的方式分配给新进程,一旦达到最大值32767,就会从低位开始检测空的pid,继续分配,每一时刻pid都是唯一确定的。
  • (3) 进程号0-299保留给daemon进程
  • (4)位置修改:/proc/sys/kernel/pid_max–看看就行啦,确实内部机制就是这样的。

猜你喜欢

转载自blog.csdn.net/weixin_39956356/article/details/86648643
今日推荐