1、管道(pipe)
用语具有亲缘关系进程间的通信
匿名一次性使用的,半双工。一个进程往输出端写管道,另一个进程从输入端读管道。
#include<unistd.h>
int pipe(int fd[2]);
fd[0]:表示读端
fd[1]:表示写端
2、有名管道(named pipe)
允许无亲缘关系进程间的通信
有名管道,作为特别文件存储于文件系统中。有名管道一旦建立就存在于文件系统中,除非显示的unlink
#include<sys/tpes.h>
#include<sys/stat.h>
int mknod(const char *path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mode);
path:创建有名管道的全路径名
mod:创建有名管道的模式,指存取权限
dev:设备值,该值取决于文件创建的种类,它只在创建设备文件时才会用到
注意:有名管道创建后就可以使用了,有名管道和管道的使用方法基本是相同的。只是使用有名管道的时候必须先调用open()将其打开
因为有名管道是一个存在于硬盘上的文件,而管道是存在于内存中的特殊文件
下面的程序一个读管道,另一个写管道,这两个函数用的是非阻塞读写管道
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"
main(int argc, char** argv)
{
char buf_r[100];
int fd;
int nread;
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
printf("cannot create fifoserver\n");
printf("Preparing for reading bytes...\n");
memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1){
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
pause();
unlink(FIFO);
}
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"
main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;
if(fd==-1)
if(errno==ENXIO)
printf("open error; no reading process\n");
fd=open(FIFO,O_WRONLY|O_NONBLOCK,0);
if(argc==1)
printf("Please send something\n");
strcpy(w_buf,argv[1]);
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf("The FIFO has not been read yet.Please try later\n");
}
else
printf("write %s to the FIFO\n",w_buf);
}
3、信号量
主要用于进程间及同一进程不同线程之间的同步手段
4、消息队列
克服信号量有限,可写可读
5、信号(Signal)
比较复杂,用于通知接受进程有某事发生
6、共享内存
最有用的进程间通信方式,使得多个进程可访问同以内存空间,但需要依靠某种同步机制
第一步:创建共享内存
第二步:映射共享内存
7、套接字
不同机器之间通信