关于pipe的使用

进程间通信(Interprocess Communication, IPC),经典的IPC:管道、FIFO、消息队列、信号量以及共享存储和套接字。


  一、管道

  管道是UNIX系统IPC的最古老的形式,所有的UNIX系统都提供此种通信机制。

  1·、两个局限性:

    (1)半双工,数据只能在一个方向流动,现在有些系统可以支持全双工管道,但是为了最佳的可移植性,应认为系统不支持全双工管道;

    (2)管道只能在具有公共祖先之间的两个进程之间使用;

  2、管道的创建:

   它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。管道是通过调用pipe函数创建的。


通过使用man 2 pipe 查看pipe的用法,使用man 7 pipe了解细节

 经由参数fd返回的两个文件描述符:pipefd[0]为读而打开,pipefd[1]为写而打开,pipefd[1]的输出是pipefd[0]的输入。通常,进程会先调用pipe,接着调用fork,从而创建了父进程与子进程的IPC通道。fork之后做什么取决于我们想要的数据流的方向,对于从父进程到子进程,父进程关闭管道的读端pipefd[0],子进程关闭写端pipefd[1]。

  3、关闭管道的一端

    (1)当读一个写端被关闭的管道时,在所有数据都被读取后,read返回0,表示文件结束;

    (2)当写一个读端被关闭的管道时,则产生信号SIGPIPE,如果忽略该信号或者捕捉该信号并从其处理程序返回,则wirte返回-1.

代码部分:如下所示

主要是通过注释掉read end 或者 write end 来实现关闭管道,以及对于管道基本的使用方法


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

#define DE

// signal process function
void sig_pipe(int signal)
{
	printf("catch the SIGPIPE signal\n");
}

// main function
int main(int argc, const char *argv[])
{
	int n;
	int pipefd[2];
	int count = 0;
	char buf[100]  = {0};
	char buff[100] = {0};

	// Register a signal for sig_pipe function
	signal(SIGPIPE,sig_pipe);

	// creat pipe for interprocess communication
	if(pipe(pipefd) < 0)
	{
		perror("fail to create pipe");
		exit(EXIT_FAILURE);
	}
	// close read end pipefd
	// close(pipefd[0]);

	printf("please input a string,what you want to say!\n");
	// gets have some dangerous fgets is better
	fgets(buff,100,stdin);
    
	if((n=write(pipefd[1],buff,sizeof(buff))) < 0)
	{
		perror("write error");
		exit(EXIT_FAILURE);
	}
	 printf("Write %d bytes : %s\n",n,buff);
	// close write end pipefd
#if 1
	close(pipefd[1]);

	// close(pipefd[0]);
#endif

#ifdef DE
	if((n=read(pipefd[0],buf,sizeof(buf))) < 0)
	{
		perror("fail to read pipe");
		exit(EXIT_FAILURE);
	}
	 printf("Rread %d bytes : %s\n",n,buf);
#endif
	
	return 0;
}

在写管道时,常量PIPE_BUF规定了内核管道的缓冲区大小,如果对管道调用write,而且要求写的字节数小于等于PIPE_BUF,则此操作不会与其他进程对同一管道的write操作交叉进行,如果多个进程对同一管道写的字节数超过PIPE_BUF,所写的数据可能会与其他进程所写的数据相互交叉。用pathconf或fpathconf函数可以获得PIPE_BUF的值。

FPATHCONF(3)              Linux Programmer's Manual             FPATHCONF(3)
NAME         top
       fpathconf, pathconf - get configuration values for files
SYNOPSIS         top
       #include <unistd.h>

       long fpathconf(int fd, int name);
       long pathconf(const char *path, int name);

DESCRIPTION         top
       fpathconf() gets a value for the configuration option name for the
       open file descriptor fd.

       pathconf() gets a value for configuration option name for the
       filename path.

       The corresponding macros defined in <unistd.h> are minimum values; if
       an application wants to take advantage of values which may change, a
       call to fpathconf() or pathconf() can be made, which may yield more
       liberal results.

       Setting name equal to one of the following constants returns the
       following configuration options:

       _PC_LINK_MAX
              The maximum number of links to the file.  If fd or path refer
              to a directory, then the value applies to the whole directory.
              The corresponding macro is _POSIX_LINK_MAX.

       _PC_MAX_CANON
              The maximum length of a formatted input line, where fd or path
              must refer to a terminal.  The corresponding macro is
              _POSIX_MAX_CANON.

       _PC_MAX_INPUT
              The maximum length of an input line, where fd or path must
              refer to a terminal.  The corresponding macro is
              _POSIX_MAX_INPUT.

       _PC_NAME_MAX
              The maximum length of a filename in the directory path or fd
              that the process is allowed to create.  The corresponding
              macro is _POSIX_NAME_MAX.

       _PC_PATH_MAX
              The maximum length of a relative pathname when path or fd is
              the current working directory.  The corresponding macro is
              _POSIX_PATH_MAX.

       _PC_PIPE_BUF
              The maximum number of bytes that can be written atomically to
              a pipe of FIFO.  For fpathconf(), fd should refer to a pipe or
              FIFO.  For fpathconf(), path should refer to a FIFO or a
              directory; in the latter case, the returned value corresponds
              to FIFOs created in that directory.  The corresponding macro
              is _POSIX_PIPE_BUF.

       _PC_CHOWN_RESTRICTED
              This returns a positive value if the use of chown(2) and
              fchown(2) for changing a file's user ID is restricted to a
              process with appropriate privileges, and changing a file's
              group ID to a value other than the process's effective group
              ID or one of its supplementary group IDs is restricted to a
              process with appropriate privileges.  According to POSIX.1,
              this variable shall always be defined with a value other than
              -1.  The corresponding macro is _POSIX_CHOWN_RESTRICTED.

              If fd or path refers to a directory, then the return value
              applies to all files in that directory.

       _PC_NO_TRUNC
              This returns nonzero if accessing filenames longer than
              _POSIX_NAME_MAX generates an error.  The corresponding macro
              is _POSIX_NO_TRUNC.

       _PC_VDISABLE
              This returns nonzero if special character processing can be
              disabled, where fd or path must refer to a terminal.

 个人书写方式如下:

	// creat pipe for interprocess communication
	if(pipe(pipefd) < 0)
	{
		perror("fail to create pipe");
		exit(EXIT_FAILURE);
	}
    printf("#####pipebuf#### %ld\n",fpathconf(pipefd[1],_PC_PIPE_BUF));
    // printf("#####pipebuf#### %ld\n",pathconf((char*)pipefd,_PC_PIPE_BUF));

#if 0
##########################################################
只需要在创建pipe后,添加函数,按照man手册上面的要求输出打印就可以。
##########################################################
#endif

精品连接https://www.cnblogs.com/funblogs/p/7675515.html

猜你喜欢

转载自blog.csdn.net/GoTime_yx/article/details/84102177