我正在学习IPC编程。作为其中的一部分,我尝试了以下两个代码来了解消息队列....
邮件队列创建者或邮件发件人
struct my_msgbuf {
long mtype;
char mtext[200];
};
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
if ((key = ftok("kirk.c", 'B')) == -1) {
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
printf("Enter lines of text, ^D to quit:\n");
buf.mtype = 1; /* we don't really care in this case */
while(fgets(buf.mtext, sizeof buf.mtext, stdin) != NULL) {
int len = strlen(buf.mtext);
/* ditch newline at end, if it exists */
if (buf.mtext[len-1] == '\n') buf.mtext[len-1] = '\0';
if (msgsnd(msqid, &buf, len+1, 0) == -1) /* +1 for '\0' */
perror("msgsnd");
}
if (msgctl(msqid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(1);
}
return 0;
}
讯息接收者
struct my_msgbuf {
long mtype;
char mtext[200];
};
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
if ((key = ftok("kirk.c", 'B')) == -1) { /* same key as kirk.c */
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, 0644)) == -1) { /* connect to the queue */
perror("msgget");
exit(1);
}
printf("spock: ready to receive messages, captain.\n");
for(;;) { /* Spock never quits! */
if (msgrcv(msqid, &buf, sizeof(buf.mtext), 0, 0) == -1) {
perror("msgrcv");
exit(1);
}
printf("spock: \"%s\"\n", buf.mtext);
}
return 0;
}
上述代码可在beej's guide for message queue找到。
当我尝试执行“spock”时,msgget()抛出一个错误:没有这样的文件或目录。 ftok()有什么问题吗?我将文件的权限更改为传递给msgget()函数的权限。但同样的错误。提前致谢。 提前谢谢。
答案 0 :(得分:4)
ftok
要求文件存在,因为它使用inode
信息来构造密钥。如果您在单独的目录中构建它们,则使用相对路径指向kirk.c
应该可以正常工作,例如spock/spock.c
包含spock代码,kirk/kirk.c
包含kirk代码,在spock/spock.c
中您应该引用../kirk/kirk.c
答案 1 :(得分:0)
也有同样的问题。如果你想执行消息接收者过程,你必须确保消息发送者当时也在执行。否则msgqueue(如果你曾经运行过消息发送者)将会被破坏,与它相关的id将不再有效。因此,它有点神奇。 Pozdr。