前言
进程的介绍已经告一段落,接下来学习的内容是进程间的通讯.
进程间通信(IPC)
面试考点:
IPC的通讯方式通常有:管道(无名和命名) ,消息队列,信号量,共享存储,socket,streams等.socket和streams支持2个不同的主机上的2个进程IPC.
管道通常指无名管道
特点:
1. 半双工(只能在一个方向上流动)
2. 只能用于具有亲缘关系的进程间通讯(父子进程or兄弟进程)
3.读写可用 read write 等函数,不属于其他任何文件系统,只存在于内存中.
局限性:
1. 同一时间只能单向(eg:父进程读,子进程写);
2. 管道数据,读完就没啦
函数原型:
#include <unistd.h>
int pipe(int fd[i]); //成功返回值为0,失败返回值为1
fd[0]为读而打开 ------>关闭--------> close fd[0]
fd[1]为写而打开 ------>关闭--------> close fd[1]
无名管道函数应用:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (){
int fd[2];
int pid ;
char buf[128];
if (pipe(fd) == -1){
printf("create pipe failed!\n");
}
pid = fork();
if (pid < 0){
printf ("create child progress failed!\n");
}
else if(pid > 0){
printf("this is father progress!\n");
close(fd[0]);
write(fd[1],"hello from father",strlen("hello from father"));
wait(&pid);
}
else{
printf("this is child progress!\n");
close(fd[1]);
read(fd[0],buf,128);
printf("read from father:%s!\n",buf);
exit(0);
}
return 0;
}
运行结果参考图:
命名管道(FIFO)
FIFO也称命名管道,是一种文件类型.
特点
1. FIFO 可以在无关的进程之间交换数据,与无名管道不同.
2. FIFO 有路径名与之相关连,它以一种特殊的设备文件形式存在与文件系统中.
函数原型
#include <sys/stat.h>
int mkfifo(const char* pathname,moode_t mode);
//成功返回值为0,失败返回值为-1
命名管道以文件的形式存储在磁盘,所以在创建FIFO之后可以用一般的I/O函数操作它.
一般read之后都会阻塞,等读取到write内容后才会回复正常.
也可以设置成非阻塞,但是不经常用于FIFO.
有名管道函数应用:
comm3.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
int main(){
if (mkfifo("./file",0600) == -1 && errno!= EEXIST)
{
printf("mkfifo failed \n");
perror("why");
}
int fd =open ("./file",O_RDONLY);
printf ("open successfully!\n ");
return 0;
}
comm4.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
int main(){
int fd =open ("./file",O_WRONLY);
printf ("write open successfully!\n ");
return 0;
}
运行编译命令及运行结果参考:
命名管道(持续收发版)
comm5.c(read)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int main(){
char buf[30] = {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 successfully!\n ");
while(1){
nread = read(fd,buf,30);
printf("Read %d byte from fifo,context = %s \n",nread,buf);
}
close(fd);
return 0;
}
comm6.c(write)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main(){
int cnt = 0;
char *str = "message from fifo.";
int fd =open ("./file",O_WRONLY);
printf ("write open successfully!\n ");
while(1){
write(fd,str,strlen(str));
sleep(1);
cnt = cnt + 1;
if (cnt == 5){
break;
}
}
close(fd);
return 0;
}
运行编译命令及运行结果参考:
上述代码是写5遍,写完后不停读取,读完之后就读不到内容了.