在Linux中使用较多的进程间通信方式主要有以下几种
1)管道Pipe
2)信号Signal
3)消息队列Message Queue:是消息的链接表
4)共享内存Shared Memory:最有效的进程间通信方式
5)信号量Semaphore:主要作为进程之间以及同一进程的不同线程之间的同步和互斥
6)套接字Socket:用于网络中不同机器之间的通信
1. pipe(建立无名管道)
表头文件 #include <unistd.h>
函数定义 int pipe(int filedes[2]);
函数说明 pipe()会建立无名管道,并将文件描述符由参数filedes数组返回,filedes[0]用于读管道,filedes[1]用于写管道
只能用于有亲缘关系的进程之间通信
2. mafifo()建立有名管道
kfifo(建立有名管道)
表头文件 #include <sys/types.h>
#include <sys/stat.h>
函数定义 int mkfifo(const char *pathname, mode_t mode);
函数说明 mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数
mode为该文件的权限(mode&~umask)
mode specifies the FIFO's permissions. It is modified by the
process's umask in the usual way: the permissions of the created file are (mode & ~umask)
.umask值也会影响到FIFO文件的权限,mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取,
当使用open()来打开FIFO文件时,O_NONBLOCK会有影响
当使用O_NONBLOCK时,打开FIFO文件读取的操作会立即返回,但是若还没有其他进程打开FIFO来读取,
则写入的操作会返回ENXIO错误代码
当没有使用O_NONBLOCK文件,打开FIFO文件读取的操作会等到其他进程打开FIFO文件来写入才正常返回,
同样,打开FIFO文件来写入的操作会等到其他进程打开FIFO文件来读取后才正常返回
1)管道Pipe
2)信号Signal
3)消息队列Message Queue:是消息的链接表
4)共享内存Shared Memory:最有效的进程间通信方式
5)信号量Semaphore:主要作为进程之间以及同一进程的不同线程之间的同步和互斥
6)套接字Socket:用于网络中不同机器之间的通信
1. pipe(建立无名管道)
表头文件 #include <unistd.h>
函数定义 int pipe(int filedes[2]);
函数说明 pipe()会建立无名管道,并将文件描述符由参数filedes数组返回,filedes[0]用于读管道,filedes[1]用于写管道
只能用于有亲缘关系的进程之间通信
成功返回0,错误返回-1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
int fd[2];
char buf[1024] = "every day is good day";
int ret=0;
if(pipe(fd) < 0) {//创建无名管道
perror("piple");
exit(1);
}
pid_t pid;
if((pid = fork()) == 0) { //创建一子进程
ret = write(fd[1], buf, strlen(buf));
if (ret < 0) {
perror("write");
exit(1);
}
printf("write %d bytes [%s]\n", ret, buf);
} else if(pid > 0) {
sleep(1);
ret = read(fd[0], buf, sizeof(buf));
printf("%d bytes read from the pipe is [%s]\n", ret, buf);
if (ret < 0) {
perror("read");
exit(1);
}
}
close(fd[0]);
close(fd[1]);
return 0;
}
----------------------------------------
/pipe# ./test
write 21 bytes [every day is good day]
21 bytes read from the pipe is [every day is good day]
2. mafifo()建立有名管道
kfifo(建立有名管道)
表头文件 #include <sys/types.h>
#include <sys/stat.h>
函数定义 int mkfifo(const char *pathname, mode_t mode);
函数说明 mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数
mode为该文件的权限(mode&~umask)
mode specifies the FIFO's permissions. It is modified by the
process's umask in the usual way: the permissions of the created file are (mode & ~umask)
.umask值也会影响到FIFO文件的权限,mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取,
当使用open()来打开FIFO文件时,O_NONBLOCK会有影响
当使用O_NONBLOCK时,打开FIFO文件读取的操作会立即返回,但是若还没有其他进程打开FIFO来读取,
则写入的操作会返回ENXIO错误代码
当没有使用O_NONBLOCK文件,打开FIFO文件读取的操作会等到其他进程打开FIFO文件来写入才正常返回,
同样,打开FIFO文件来写入的操作会等到其他进程打开FIFO文件来读取后才正常返回
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO "/tmp/myfifo" //有名管道文件名
int main(int argc, char **argv)
{
int fd;
int ret = 0;
umask(0);
char buf[]="hello world";
char buf1[1024];
if (mkfifo(FIFO, 07777) < 0) {
perror("mkfifo");
exit(1);
}
pid_t pid;
if ((pid = fork()) == 0){
fd = open(FIFO, O_WRONLY);
ret = write(fd, buf, strlen(buf));
printf("write %d bytes, [%s]\n", ret, buf);
close(fd);
} else if(pid > 0) {
sleep(1);
fd = open(FIFO, O_RDONLY);
ret = read(fd, buf1, sizeof(buf1));
printf("read %d bytes, [%s]\n", ret, buf);
close(fd);
}
}
-----------------------------------------------------
/myfifo# ./test
write 11 bytes, [hello world]
read 11 bytes, [hello world]
第二次运行
myfifo# ./test
mkfifo: File exists
因为管道也经创建了
myfifo# ls /tmp/myfifo
/tmp/myfifo