进程间通信:
1、古老的进程间通信:
无名管道 有名管道 信号
2、IPC通信方式:
消息队列对象 共享内存对象 信号量集对象
3、SOCKET通信方式:
TCP UDP
古老的通信方式:
1、管道 ===》无名管道/有名管道
公共特性:
1、管道的操作框架;
创建管道 ===》打开管道 ==》读写管道 ==》关闭管道 ==》销毁管道
2、所有管道都是 半双工 工作模式
3、管道是一类特殊文件,操作方式为文件IO,且不支持定位操作;
4、管道的通信过程必须保证同步;
1.1 无名管道的使用:===》PIPE ===pipe
私有特性: 没有名称,基于内存;
只能用于亲缘关系进程间通信;
必须在fork调用之前创建;
创建无名管道/打开管道;
#include <unistd.h>
int pipe(int pipefd[2]);
功能:该函数可以创建并打开一个无名管道。
参数:整形数组,有两个元素;
pipefd[0] 管道的固定读端
pipefd[1] 管道的固定写端
返回值:成功 0
失败 -1;
读写无名管道:用文件io操作
读: ssize_t read(int fd, void *buf, size_t count);
写: ssize_t write(int fd, const void *buf, size_t count);
关闭管道: close();
建议在不进行读写操作的进程中将相关管道端关闭;
销毁管道: 无
管道的同步; 如果一个有效管道通信过程,必须保证读写端同步;
=》如果读端存在则必须写端存在
-》如果写端存在则必须读端存在
验证:如果只有读端,没有写端会有什么异常?===》read不阻塞;
如果只有写端,没有读端会有什么异常?===》SIGPIPE异常终止
===》必须保证读写端同步;
读写端是一定固定的吗?能不能互换?
不能互换,都是固定的读写端;
//无名管道读操作
#include <stdio.h>
#include <unistd.h>
#define N 1024
int main()
{
int fd[2];
char buf[N]="";
ssize_t n;
int count=0;
if(pipe(fd)<0)
{
perror("pipe error\n");
return -1;
}
while(1)
{
n=read(fd[0],buf,N);
//count++;
printf("n=%d\n",n);
}
}
//无名管道写操作
#include <stdio.h>
#include <unistd.h>
#define N 1024
int main()
{
int fd[2];
char buf[N]="";
int i=0;
for(i=0;i<N;i++)
{
buf[i]='a';
}
int count=0;
if(pipe(fd)<0)
{
perror("pipe error");
return -1;
}
while(1)
{
write(fd[1],buf,N);
count++;
printf("count=%d\n",count);
}
}