进程间通信(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