何为进程间通信
进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。另外,系统空间是"公共场所",各进程均可以访问,所以内核也可以提供这样的条件。此外,还有双方都可以访问的外设。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过"注册表"或其它数据库中的某些表项和记录交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作"进程间通信"。
分类
1 简单进程间通信:
命令行参数、环境变量、信号、文件。
2 传统进程间通信:
管道(fifo/pipe)。
3 XSI进程间通信:
共享内存、消息队列、信号量。
4 网络进程间通信:
套接字socket。
关于简单进程间通信的方式前面已经讲过
接下来看看其他的5种
管道
概念:
管道是Linux支持的最初UnixIPC形式之一,具有以下特点:
管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
有名管道
我们通过创建客户端和服务端来读写
服务器
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int running = 1;
#define FIFO1 "/tmp/wfifo"
#define FIFO2 "/tmp/rfifo"
void sigint_proc(int sig){
running = 0;
}
int main(){
signal(SIGINT,sigint_proc);
int ret = mkfifo(FIFO1,0664);
if(ret == -1){
perror("mkfifo");
return -1;
}
ret = mkfifo(FIFO2,0664);
if(ret == -1){
perror("mkfifo");
return -1;
}
int wfd = open(FIFO1,O_RDWR|O_NONBLOCK);//打开管道用于写
int rfd = open(FIFO2,O_RDWR|O_NONBLOCK);//打开管道用于读
if(wfd == -1||rfd == -1){
perror("open");
return -1;
}
pid_t id;
id = fork();
if(id == -1){
perror("fork");
close(wfd);
close(rfd);
}
if(id == 0){
for(;running;){
char str[128] = {
};
fgets(str,128,stdin);
if(write(wfd,str,strlen(str))<0){
//在这个函数中阻塞
break;
}
}
}else{
for(;running;){
char str[128] = {
};
if(read(rfd,str,128)<0){
if(errno == EAGAIN){
continue;
}
break;
}else
printf("recv: %s",str);
}
}
close(rfd);
close(wfd);
unlink(FIFO1);
unlink(FIFO2);
return 0;
}
客户端
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#define FIFO1 "/tmp/wfifo"
#define FIFO2 "/tmp/rfifo"
int main(){
int wfd = open(FIFO2,O_RDWR);//打开管道用于写
int rfd = open(FIFO1,O_RDWR);//打开管道用于读
if(wfd == -1||rfd == -1){
perror("open");
return -1;
}
pid_t id;
id = fork();
if(id == -1){
perror("fork");
close(wfd);
close(rfd);
}
if(id == 0){
for(;;){
char str[128] = {
};
fgets(str,128,stdin);
if(write(wfd,str,strlen(str))<=0)