浅谈UNIX网络编程system V IPC机制
进程间通信(IPC,Inter-Process Communication)指至少两个进程或线程间传送数据或信号的一些技术或方法。 一.System V IPC 的构成1.system v消息队列 2.system v信号量 3.system v共享内存 我们把这三种工具统称为System V IPC的对象,每个对象都具有一个唯一的IPC标识符(identifier)。要保证不同的进程能够获取同一个IPC对象,必须提供一个IPC关键字(IPC key),内核负责把IPC关键字转换成IPC标识符。
** 二.Ftok函数** 系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。 ftok原型如下: **key_t ftok( char * fname,int id )** fname就时你指定的文件名(该文件必须是存在而且可以访问的),**id是子序号,虽然为int,但是只有8个比特被使用(0-255)。** 当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,换算成16进制为 0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。 三.创建与打开IPC通道 四.创建通道-getXXX函数通常我们使用getxxx函数来创建或者访问一个已知的通道。 int msgget(key_t key,int flag);
int semget(key_t key,int nsems,int flag);
int shmget(key_t key,size_t size,int flag);
这个函数都有一个flag参数(由逻辑或组成),该参数也可类比open函数的flag参数,虽然取值不尽相同。这三个函数的flag取值是一样的。 IPC_CREAT 如果key不存在,则创建(类似open函数的O_CREAT) IPC_EXCL 如果key存在,则返回失败(类似open函数的O_EXCL) IPC_NOWAIT 如果需要等待,则直接返回错误 用一个图表更能体现其中的逻辑
另外oflag中的参数也将初始化ipc_perm结构中的mode成员。其中权限有一个简单的记忆方法,就是和linux中的权限是一样的,比如说你给一个0644系统将识别为MSG_R|MSG_W|MSG_R>>3|MSG_R>>6 五.控制函数——xxxctl函数int msgctl(int msqid,int cmd,struct msqid_ds *buf);
int semctl(int semid,int semmun,.../*union semun arg */);
int shmctl(int shmid,struct shmid_ds *buf);
三个ctl控制函数其实是在操作三种IPC机制对应的三种数据结构: msqid_ds semid_ds shmid_ds 它们有共同的后缀——id_ds。ds就是data structure(数据结构)的意思。
semctl函数有更复杂的作用,我们在稍后再谈。 五.操作函数操作函数在不同的体系中有着不一样的作用。 int msgsnd(int msqid,const void *ptr,size_t length,int flag);
ssize_t msgrcv(int msqid,void *ptr,long type,int flag);
其中 ptr所指向的结构需要自己构造,通常是这样 struct msgbuf
{
long mtype;
char mtetx[MAX_LINE];
}
在msgsnd中 size_t 应该为发送的mtetx的长度可以用strlen(mtetx)+1 在信号量中 int semop(int semid,struct sembuf *opsptr,size_t nops);
opsptr指向sembuf struct sembuf
{
short sem_num;
short sem_op;
short sem_flag;
}
用于操作信号集中sem_num的信号量的增减,增减量由sem_op来决定。 在共享内存区中 int shmdt(const void *shmaddr);
void *shmat(int shmid,const void *shmaddr,int flag);
shmat函数是将共享内存区链接到调用的进程空。 六.小技巧-包裹函数在UNIX网络编程中常常出现一些首字符大写的函数,这些是包裹函数,包裹了出错处理。有些函数不止。 int Semop(int semid,size_t size)
{
int ret = semop(semid,opsptr,size);
if (ret == -1)
{
perror("semget:");
exit(0);
}
return ret;
}
这样可以大量节省编程时间和代码量。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |