进程间通信IPC介绍
进程间通信是指不同进程之间交换信息
IPC方式通常有管道(包括无名管道,命名管道),消息队列,信号量,共享存储,Socket,stream等
其中Socket,stream支持以linux中的c语言编程
一,管道
管道,通常为无名管道,是UNIX系统IPC最古老的方式
1,特点:
1.它是半双工,具有固定的读端和写端
2.其次具有亲缘关系的进程之间的通信(父子进程或者兄弟进程)
3.它可以被看成一种特殊的文件,对于它的读写也可以使用普通read,write等函数,它不是普通的文件,并不属于其他文件系统,并且只存在于内存中。
#include <unistd.h>
int pipe(int pipefd[2]); //返回值,若成功返回0,失败返回-1
当一个管道建立,它会创建两个文件描述符,fd[0]为读而打开,fd[1]为写而打开
要关闭管道只需要将这两个fd文件关闭机可
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
// int pipe(int pipefd[2]);
int main()
{
int fd[2];
pid_t pid;
char buff[20];
if(pipe(fd) < 0)
{
printf("pipe failed");
}
if((pid = fork()) < 0)
printf("fork failed");
else if(pid > 0) //创建父进程
{
close(fd[0]); //关闭读端
write(fd[1],"hello,world\n",20);
}
else{ //创建子进程
close(fd[1]); //关闭写端
read(fd[0],buff,20);
printf("%s",buff);
}
return 0;
}
二,FIFO
FIFO.也称之为命名管道,它是一种文件类型
1,特点
1.FIFO可以在无关的进程之间交换数据,与无名管道不同
2.FIFO有路径名与相关联,它以一种特殊设备文件形式存在于文件系统中
2.代码原型
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
创建管道
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
// int mkfifo(const char *pathname, mode_t mode);
int main()
{
int ret = mkfifo("./file",0600);
if(ret == 0){
printf("mkfifo success \n");
}
if(ret == -1)
{
printf("mkfifo failed \n");
}
return 0;
}
~
1 #include <sys/stat.h>
2 // 返回值:成功返回0,出错返回-1
3 int mkfifo(const char *pathname, mode_t mode);
当 open 一个FIFO时,是否设置非阻塞标志(O_NONBLOCK
)的区别:
-
若没有指定
O_NONBLOCK
(默认),只读 open 要阻塞到某个其他进程为写而打开此 FIFO。类似的,只写 open 要阻塞到某个其他进程为读而打开它。 -
若指定了
O_NONBLOCK
,则只读 open 立即返回。而只写 open 将出错返回 -1 如果没有进程已经为读而打开该 FIFO,其errno置ENXIO
//read.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
// int mkfifo(const char *pathname, mode_t mode);
int main()
{
char buf[1024] = {0};
int nread =0;
if((mkfifo("./file",0600) == -1) && errno!= EEXIST)
{
printf("mkfifo failed \n");
perror("why");
}
int fd = open("./file",O_RDONLY);
printf("open success \n");
while(1){
nread = read(fd,buf,30);
printf("read %d byte from fifo context %s\n",nread,buf);
}
close(fd);
return 0;
}
~
//write.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
//
// int mkfifo(const char *pathname, mode_t mode);
int main()
{
int cnt =0;
char *str = "sky";
int fd = open("./file",O_WRONLY);
printf("write open success \n");
while(1)
{
write(fd,str,strlen(str));
sleep(1);
if(cnt ==5){
break;
}
}
close(fd);
return 0;
}
实验结果