进程间通信
进程间通信:进程之间交换数据的过程叫进程间通信。
进程间通信的方式:
简单的进程间通信:
命令行:父进程通过exec函数创建子进程时可以附加一些数据。
环境变量:父进程通过exec函数创建子进程顺便传递一张环境变量表。
信号:父子进程之间可以根据进程号相互发送信号,进程简单通信。
文件:一个进程向文件中写入数据,另一个进程从文件中读取出来。
命令行、环境变量只能单身传递,信号太过于简单,文件通信不能实时。
XSI通信方式:X/open 计算机制造商组织。
共享内存、消息队列、信号量
网络进程间通信方式:
网络通信就是不同机器的进程间通信方式。
传统的进程间通信方式:
管道
管道
有名管道(这种管道是以文件方式存在的)。
int mkfifo(const char *pathname, mode_t mode);
管道通信的编程模式:
进程A 进程B
创建管道mkfifo
打开管道open 打开管道
写/读数据read/write 读/写数据
关闭管道close 关闭管道
简单实现管道通信:
file A:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
int main()
{
// 创建管道文件
if(0 > mkfifo("/home/jgx/test.txt",0644))
{
perror("mkfifo");
return -1;
}
// 打开
int fd = open("/home/afc/test.txt",O_RDWR);
if(0 > fd)
{
perror("open");
return -1;
}
// 准备缓冲区
char buf[255] = {};
// 写/读
while(1)
{
printf(">");
gets(buf);
int ret = write(fd,buf,strlen(buf));
printf("写入数据%d字节\n",ret);
if('q' == buf[0])break;
getchar();
bzero(buf,sizeof(buf));
ret = read(fd,buf,sizeof(buf));
printf("读取数据%d字节,内容:%s\n",ret,buf);
if('q' == buf[0])break;
}
// 关闭
close(fd);
}
file B:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <strings.h>
int main()
{
int fd = open("/home/jgx/test.txt",O_RDWR);
if(0 > fd)
{
perror("open");
return -1;
}
char buf[255] = {};
while(1)
{
bzero(buf,sizeof(buf));
int ret = read(fd,buf,sizeof(buf));
printf("读取数据%d字节,内容:%s\n",ret,buf);
if('q' == buf[0]) break;
printf(">");
gets(buf);
ret = write(fd,buf,strlen(buf));
printf("写入数据%d字节\n",ret);
if('q' == buf[0]) break;
getchar();
}
close(fd);
}
编译运行结果:
./a
>123
写入数据3字节
q
读取数据1字节,内容:q
./b
读取数据3字节,内容:123
>q
写入数据1字节
注:在虚拟机的共享文件夹下无法创建管道!
无名管道
由内核帮助创建,只返回管道的文件描述符,看不到管道文件,但这种管道只能用在fork创建的父子进程之间(同一个进程间也可以使用)。
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd[2] = {};
pipe(fd);//fd[0]是读,fd[1]是写
if(fork() != 0)
{
write(fd[1],"hello",5);
}
else
{
char buf[128] = {0};
read(fd[0],buf,127);
printf("%s\n",buf);
}
close(fd[0]);
close(fd[1]);
}