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. 

这些是一个接一个地运行,其间没有对代码进行任何更改。