为什么进程间需要通信????
因为一个庞大的项目,肯定需要多个进程相互协作的,我们的进程内存空间是相互独立的,
所有我们不能定义一块他们共享的空间,实现数据的交互,只能使用其它方式实现,进程之间的数据交互。
进程之间的通信方式有如下:
1.文件 (远古时代的通信方式,因为他的效率很低,基本不使用)
2.管道 (在文件的基础上改进的通信方式)
3.信号 (效率较高,但是传输数据不方便,只能传输整形数,有点像中断)
4.IPC通信:
1.消息队列
2.共享内存
3.信号量(不负责通信,只负责保护通信时的安全)
管道通信:
无名管道: 只用于父子进程之间的通信。
有名管道: 可用于不同进程之间的通信。(也可以用于父子之间)
管道文件不是可以无穷写入的,当管道写满后,写函数会阻塞。(等待别人把数据读走)
当管道没有数据时,读取管道会阻塞。
//无名管道的创建
#include <unistd.h>
//创建一个无名管道
int pipe(int pipefd[2]);
参数一:无名管道的两个端口 (读.写)
返回值: 0 成功
-1 失败
pipefd[1] ->写端
pipefd[0] ->读端
有名管道的创建:
1.使用命令的方式创建
mkfifo 文件名
(注意:共享目录不支持管道文件)
2.使用函数的方式创建管道
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
//参数一:需要创建的管道路径
//参数二:权限
(mode & ~umask).
返回值:成功返回 0
失败返回 -1
操作有名管道
1.打开管道文件 open
2.读写管道 read/write
3.关闭管道 close
PS:1.管道文件的数据是先进先出的
2.管道文件的读写都会阻塞 (当写满是,当没有数据时)
3.管道文件是否可以用lseek偏移光标???(绝对不可以的!!!破坏先进先出 的逻辑)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
//创建一个无名管道
int pipefd[2]={0};
int fd=pipe(pipefd);
if(fd != 0)
{
perror("创建管道失败\n");
return 0;
}
pid_t pid = fork();
if(pid > 0)
{
char buf[10]={0};
sleep(1);
//读数据
read(pipefd[0],buf,10);
printf("get:%s\n",buf);
close(pipefd[0]);
}
else if(pid ==0)
{
//写入数据到管道中
int ret=write(pipefd[1],"abcd",4);
printf("len=%d\n",ret);
close(pipefd[1]);
}
return -1;
}
运行效果如下图:
#include <stdio.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
if(access("/home/gec/pipe",F_OK)) //返回0则存在,则不会执行创建命令
{
//创建管道文件
int fd = mkfifo("/home/gec/pipe",0666);
if(fd < 0)
{
perror("creat fail\n");
exit(0);
}
}
//打开管道
int pipefd = open("/home/gec/pipe",O_RDWR);
if(pipefd < 0)
{
perror("open fail\n");
exit(0);
}
//创建进程,使读写同步进行
pid_t pid = fork();
if(pid == 0) //子进程写
{
char buf[1024]={0};
while(1)
{
memset(buf, 0, sizeof(buf));
//写入数据到管道中
scanf("%s",buf);
write(pipefd,buf,strlen(buf));
if(strcmp(buf,"exit")==0)
{
printf("1退出成功\n\n");
exit(0);
}
}
}
if(pid > 0) //父亲读
{
char buf[1024]={0};
while(1)
{
memset(buf, 0, sizeof(buf));
read(pipefd,buf,1024);
printf("get:%s\n",buf);
if(strcmp(buf,"exit")==0)
{
printf("2退出成功\n\n");
close(pipefd);
exit(0);
}
}
}
}
运行效果如下图: