C – 使用队列在线程之间传递消息的问题
我正在尝试使用队列在两个线程之间传递消息,但到目前为止我还没有得到任何结果。 当我在收到邮件之后和邮件发送之前打印邮件内容时,它似乎只能保持其价值。 我需要用1个服务器线程和多个客户端线程来实现它,但是现在我只使用1个。 这是我的代码
struct msg //struct for client requests to server { long mtype; int numResources; //number of resources to be requested int ID; //ID associated with client thread }; int c1PID; //process ID variable for client thread 1 int serverPID; key_t key1; key_t keyS; int msqid1; int msqidS; int main(int arc, char *argv[]) { key1 = ftok(".", '1'); //queue for client thread 1 to receive msgs from server msqid1 = msgget(key1, 666 | IPC_CREAT); keyS = ftok(".", 's'); //general queue for server msqidS = msgget(keyS, 666 | IPC_CREAT); pthread_t threads[2]; //create an array of pthreads if ((serverPID = pthread_create(&threads[0], NULL, server, NULL)) != 0) { perror("server thread"); exit(1); } if ((c1PID = pthread_create(&threads[1], NULL, client, NULL)) != 0) { perror("client thread"); exit(1); } pthread_exit(NULL); } void *server() { struct msg request; size_t size = sizeof(struct msg) - offsetof(struct msg, numResources); while (1) { msgrcv(msqidS, &request, size, 2, 0); printf("received: numResources requested = %d\n", request.numResources); request.numResources = 9001; printf("sending: numResources requested = %d\n", request.numResources); msgsnd(msqid1, &request, size, 0); sleep(1); } } void *client() { struct msg request; size_t size; request.numResources = 0; size = sizeof(struct msg) - offsetof(struct msg, numResources); msgsnd(msqidS, &request, size, 0); while(1) { msgrcv(msqid1, &request, size, 2, 0); printf("received: numResources requested = %d\n", request.numResources); request.numResources += 1;//(int)(ceil((double)(rand()%2)) + 1); printf("sending: numResources requested = %d\n", request.numResources); msgsnd(msqidS, &request, size, 0); sleep(1); }
我拿出了很多我的打印语句,但它看起来像这样:
Server thread: received: numResources = 9001; sending: numResources = 9001; client thread: received: numResources = 1; sending: numResources = 2; Server thread: received: numResources = 9001; sending: numResources = 9001; client thread: received: numResources = 2; sending: numResources = 3;
编辑:sizeof(struct msg) – offsetof(struct msg,numResources); 应该可以。
但是,根据文档 ,你的mtype
必须是一个正整数。 将其初始化为2,因为您对msgrecv的调用表示只接收消息类型2。
将错误检查添加到所有msgsnd / msgrecv调用,因此您确定没有默默地收到错误。
将错误检查添加到您的ftok和msgget调用。
您的问题是您已在消息队列上设置了无意义的权限。 在这些行中,您使用了十进制常量666
,您应该使用八进制常量0666
:
msqid1 = msgget(key1, 666 | IPC_CREAT); msqid1 = msgget(key1, 666 | IPC_CREAT);
这意味着您已经创建了具有八进制权限01232
的队列,该权限不包括读取权限 – 因此您的后续msgget()
调用现在都无法使用EPERM
(如果您检查这些调用是否有错误,您将会看到)。
您必须删除消息队列,并允许程序使用正确的权限重新创建它们。 您需要将带有IPC_RMID
命令的队列的IPC_RMID
用于msgctl()
来执行此操作,如以下程序中所示:
#include #include #include #include #include int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s [ ...]\n", argv[0]); return 1; } while (*++argv) { int msqid = atoi(*argv); printf("Removing msqid %d\n", msqid); if (msgctl(msqid, IPC_RMID, NULL) != 0) { perror("msgctl"); return 2; } } return 0; }
由于SYS V消息队列设计糟糕,您无法再从msgget()
获取msqid
值,因为msgget()
失败。 要获取要删除的msqid
值,请查看文件/proc/sysvipc/msg
。
PS:
我强烈建议使用POSIX消息队列( mq_open()
, mq_send()
, mq_receive()
等)。 界面得到显着改善。
这是它在运行中打印出来的效果。
program starting Msg sent from client *****In client thread***** Msg received by client received: numResources requested = 0 sending: numResources requested = 1 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 1 sending: numResources requested = 9001 Msg sent from server. *****In client thread***** Msg received by client received: numResources requested = 9001 sending: numResources requested = 9002 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 9002 sending: numResources requested = 9001 Msg sent from server. *****In client thread***** Msg received by client received: numResources requested = 9001 sending: numResources requested = 9002 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 9002 sending: numResources requested = 9001 Msg sent from server. *****In client thread***** Msg received by client received: numResources requested = 9001 sending: numResources requested = 9002 Msg sent from client
之后……
program starting Msg sent from client *****In client thread***** Msg received by client received: numResources requested = 9001 sending: numResources requested = 9002 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 0 sending: numResources requested = 9001 Msg sent from server. *****In client thread***** Msg received by client received: numResources requested = 9002 sending: numResources requested = 9003 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 9001 sending: numResources requested = 9001 Msg sent from server. *****In client thread***** Msg received by client received: numResources requested = 9003 sending: numResources requested = 9004 Msg sent from client *****In server thread***** Msg received by server received: numResources requested = 9001 sending: numResources requested = 9001 Msg sent from server.
这些是一个接一个地运行,其间没有对代码进行任何更改。