ipc 通信介绍
linux应用开发中,进程中通信的使用是不可能避免的,本文介绍常用的进程间通信方式。有名管道,消息队列,域套接字。
一,有名管道
管道文件,可以由任意进程访问,打开管道就可以指定读写方式
通过文件IO操作,内容在内存中,读写端全部关闭就释放,使用时注意,读端打开是会阻塞,写端打开时才运行,写端存在但是不写数据,读端也会阻塞,可以使用open read write进行读写,一但读到文件末尾,需要关闭,否则一直读到“”,返回为0。
代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc, const char *argv[])
{
int fd;
char ch;
mknod("/home/colin/test/fifo_test",S_IFIFO|0666,0);
fd = open("/home/colin/test/fifo_test",O_RDONLY);
printf("open fifo is success \n");
while(1)
{
if(!read(fd,&ch,1))
{
sleep(1);
close(fd); //这里注意,如果不关闭,一旦另外写管道了 这边就会一直从管道读,即使读不到也不会停下来
fd = open("/home/test/fifo_test",O_RDONLY);
printf("reopen fifo \n");
continue;
}
else
{
printf("read fifo is %x\n",ch);
}
}
return 0;
}
实测
运行程序,产生管道文件,并且阻塞到open之后 读之前
另外一个进程写管道时,读进程才会取消阻塞
这里注意代码中的描述:
一旦管道 阻塞到读到数据后,如果读到文件末尾不关闭 管道,程序就回一直从管道中读数据,如果没有数据就返回0。
二. 消息队列
1.消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.
2.消息队列允许一个或多个进程向它写入与读取消息.
3.管道和命名管道都是通信数据都是先进先出的原则。
4.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。
目前主要有两种类型的消息队列:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。系统V消息队列是随内核持续的,只有在内核重起或者人工删除时,该消息队列才会被删除。
代码实现,这里不写测试程序了
//初始化两个消息队列
int msg_queue_init(void)
{
key_t key_s;
int ret = 0;
if ((key_s = ftok("/etc", 'm')) == -1) // send queue
{
log_dbg("fail to ftok");
ret = -1;
}
if((msgid1 = msgget(key_s, IPC_EXCL)) < 0)
{
if((msgid1 = msgget(key_s,0666 | IPC_CREAT)) < 0)
{
log_dbg("msget1 error");
ret = -1;
}
}
else
{
log_dbg("msgid exist, msgid = %d\n", msgid1);
}
return ret;
}
//定义消息类型
struct msgbuf{
int mtype;
char buf[100<