先预览一下今天要玩的几组函数:
msgget msgctl msgrcv msgsnd ->消息队列
shmget shmctl shmat shmdt ->共享内存
semget semctl semop ->信号量
找到一点相同点了吧,get->ctrtl;message receive send;shm at->dt;sem operation;
先来玩msg:
willisway1:
#include
#include #include #include
#include "comm.h"
#define SIZE 1024
int main(void)
{
key_t key;
int ret;
char buf[SIZE];
getcwd(buf, SIZE);
key = ftok(buf, PROJNO);
ret = msgget(key, IPC_CREAT | 0600);
printf("ret = %d\n", ret);
return 0;
}
分析:创建一个消息队列,首先需要一个key值,可以理解为消息队列的描述符;这个key值由ftok得到,即为ftok的返回值;所谓消息队列,本质上还是一段内存,一段特殊用途的内存,为了操作这段内存,至少两个条件,指针和大小;getcwd获取当前目录,试着删除那一行,看看会出什么问题。
willisway2:
#include
#include #include #include
#include "comm.h"
#define SIZE 1024
struct student {
long type;
char name[SIZE];
int chinese;
int math;
};
int main(void)
{
char buf[SIZE];
int key, ret;
int msgid;
struct student stu = { 1, "stu01", 60, 60 };
getcwd(buf, SIZE);
key = ftok(buf, PROJNO);
if (key == -1)
{
perror("ftok");
return -1;
}
msgid = msgget(key, 0);
if (msgid == -1)
{
perror("msgget");
return -1;
}
printf("msgid = %d\n", msgid);
ret = msgsnd(msgid, &stu, sizeof(stu) - sizeof(long), 0);
if (ret != 0)
{
perror("msgsnd");
return -1;
}
return 0;
}
分析:msgsnd首先需要msgid,send目标地址的指针,send的大小。
willisway3:
#include
#include #include #include
#include "comm.h"
#define SIZE 1024
struct student {
long type;
char name[SIZE];
int chinese;
int math;
};
int main(void)
{
char buf[SIZE];
int key, ret;
int msgid;
struct student stu;
getcwd(buf, SIZE);
key = ftok(buf, PROJNO);
if (key == -1)
{
perror("ftok");
return -1;
}
msgid = msgget(key, 0);
if (msgid == -1)
{
perror("msgget");
return -1;
}
printf("msgid = %d\n", msgid);
ret = msgrcv(msgid, &stu, sizeof(stu) - sizeof(long), 0, 0);
if (ret == -1)
{
perror("msgrcv");
return -1;
}
printf("name = %s, chinese = %d, math = %d\n", stu.name, stu.chinese, stu.math);
return 0;
}
分析:msgsnd msgrev参数大致相同,也需要msgid,内存地址。
这就是消息队列的处理机制,看懂了一点都不复杂,并且参数的格式都有很强的规律性。