上面的头文件定义了一个名为 queuedMessage 的结构类型,它带有 payload (字节数组)和 type (整数)这两个域。该文件也定义了一些符号常数(使用 #define 语句),前两个常数被用来生成一个 key ,而这个 key 反过来被用来获取一个消息队列的 ID。ProjectId 可以是任何正整数值,而 PathName 必须是一个存在的、可访问的文件,在这个示例中,指的是文件 queue.h 。在 sender 和 receiver 中,它们都有的设定语句为:
key_t key = ftok(PathName, ProjectId); /* generate key */ int qid = msgget(key, 0666 | IPC_CREAT); /* use key to get queue id */
ID qid 在效果上是消息队列文件描述符的对应物。
示例 5. sender 程序
#include <stdio.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdlib.h> #include <string.h> #include "queue.h" -
void report_and_exit(const char* msg) { [perror][6](msg); [exit][7](-1); /* EXIT_FAILURE */ } -
int main() { key_t key = ftok(PathName, ProjectId); if (key < 0) report_and_exit("couldn't get key..."); int qid = msgget(key, 0666 | IPC_CREAT); if (qid < 0) report_and_exit("couldn't get queue id..."); -
char* payloads[] = {"msg1", "msg2", "msg3", "msg4", "msg5", "msg6"}; int types[] = {1, 1, 2, 2, 3, 3}; /* each must be > 0 */ int i; for (i = 0; i < MsgCount; i++) { /* build the message */ queuedMessage msg; msg.type = types[i]; [strcpy][11](msg.payload, payloads[i]); -
/* send the message */ msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT); /* don't block */ [printf][10]("%s sent as type %i\n", msg.payload, (int) msg.type); } return 0; }
上面的 sender 程序将发送出 6 个消息,每两个为一个类型:前两个是类型 1,接着的连个是类型 2,最后的两个为类型 3。发送的语句:
msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT);
被配置为非阻塞的(IPC_NOWAIT 标志),是因为这里的消息体量上都很小。唯一的危险在于一个完整的序列将可能导致发送失败,而这个例子不会。下面的 receiver 程序也将使用 IPC_NOWAIT 标志来接收消息。
示例 6. receiver 程序
#include <stdio.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdlib.h> #include "queue.h" -
void report_and_exit(const char* msg) { [perror][6](msg); [exit][7](-1); /* EXIT_FAILURE */ } int main() { key_t key= ftok(PathName, ProjectId); /* key to identify the queue */ if (key < 0) report_and_exit("key not gotten..."); int qid = msgget(key, 0666 | IPC_CREAT); /* access if created already */ if (qid < 0) report_and_exit("no access to queue..."); -
int types[] = {3, 1, 2, 1, 3, 2}; /* different than in sender */ int i; for (i = 0; i < MsgCount; i++) { queuedMessage msg; /* defined in queue.h */ if (msgrcv(qid, &msg, sizeof(msg), types[i], MSG_NOERROR | IPC_NOWAIT) < 0) [puts][12]("msgrcv trouble..."); [printf][10]("%s received as type %i\n", msg.payload, (int) msg.type); } -
/** remove the queue **/ if (msgctl(qid, IPC_RMID, NULL) < 0) /* NULL = 'no flags' */ report_and_exit("trouble removing queue..."); return 0; }
(编辑:ASP站长网)
|