管道是一种古老的进程间的通信方式了,除此之外还有消息队列,共享内存,信号量,这三种方式成为IPC.理解这些首先要对操作系统有一定的了解,不然总是感觉云里雾里的。消息队列信号量和共享内存是属于S月stem V标准,不同版本的linux对POSIX支持不尽相同,但是对System V提供了良好的支持。IPC可以通过shell,也可以通过编程接实现。
1.shell环境控制IPC,.
ipc对象一经创建,系统内核为该对象分配相关的数据结构,提供了相关的IPC命令.
ipcs [-asmq] 用来查看IPC对象信息,具体man 查看该命令输出含义
ipcs[-smq] ID用来删除
进程间的通信关键字,是为了区分不同的进程间的通信对象,Linux每个对象都有一个名字,用key标明。全局唯一,类似与文件系统的文件名,通过文件名,多个进程可以读写一
个文件,通过键不同进程可以访问一个IPC对象。创建IPC对象制定的关键字是IPC_PRIVATE,还可以通过调用 ftok函数。对IPC的对象访问是通过标识符来访问,类似于文件的文件
描述符,不同的是不同的进程打开同一个IPC对象返回的IPC标识符是相同的,至于文件有可能不同,我懂的,操作系统文件的共享机制决定的。
消息队列入队成为发送消息,出队为接受消息消息有类型,对于相同类型的消息,先进入消息队列的消息先被接收。
下面是一个例子:创建一个消息队列,并向其中发送一条消息,然后子进程读取消息并输出
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef struct
{
long int nType;
char szText[256];
}MSG;
int main()
{
key_t lKey;
int nMsgId;
MSG msg;MSG msg2;
int n;
if((lKey = ftok("/etc/profile",5)) == -1)
{
perror("ftok");
exit(1);
}
if((nMsgId = msgget(lKey,IPC_CREAT|IPC_EXCL|0666)) == -1)
{
if(errno != EEXIST)
{
perror("msgget");
exit(2);
}
if((nMsgId = msgget(lKey,0)) == -1)
{
perror("msgget");
exit(3);
}
}
memset(&msg,0x00,sizeof(MSG));
msg.nType = 2;
memcpy(msg.szText,"hello",5);
if(msgsnd(nMsgId,(const void *)&msg,strlen(msg.szText),IPC_NOWAIT) < 0)
{
perror("msgsnd");
}
if(fork()==0)//创建进程读刚才队列消息
{
if((n=msgrcv(nMsgId,(void *)&msg2,sizeof(msg2.szText),2L,0))<0)
{
perror("msgrcv");
}
else
{
printf("msgrcv return length=[%d] text=[%s]\n",n,msg.szText);
}
exit(0);
}
return 0;
}
再次输入ipcs -q也会发现队列里面存在消息已用字节数是5,消息个数是1.正确