Posix消息队列接收/发送/打开不起作用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Posix消息队列接收/发送/打开不起作用?相关的知识,希望对你有一定的参考价值。

我想发送和接收带有两个线程到线程队列的消息。但我也无法创建队列。当我创造一个职业时,孩子就会工作。我可以在主进程和子进程之间发送和读取消息,但我无法在线程之间工作。为什么?

资源:

#include <fcntl.h>
#include <mqueue.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "tm_api.h"

#define QUEUE_NAME  "/testqueue"
#define MAX_SIZE    1024

static void * queue_server(void *pars);
static void * queue_client(void *parc);

static void * queue_server(void *pars) {
    mqd_t mq;
    unsigned int sender;
    int bytes_read;

    struct mq_attr attr;
    char buffer[MAX_SIZE];

    attr.mq_flags   = 0;
    attr.mq_maxmsg  = 10;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY | O_NONBLOCK, 0644, &attr);
    printf("mq_receive : %d
", mq);
    memset(buffer, 0x00, sizeof(buffer));
    mq_unlink (QUEUE_NAME);
    while(1) {

        bytes_read = mq_receive(mq, buffer, MAX_SIZE, &sender);
        if(bytes_read >= 0) {
            printf("SERVER: Received message: %s
", buffer);
        } else {
            printf("SERVER: None 
");
        }

        fflush(stdout);
        tm_thread_sleep(1);
    }

    mq_close(mq);
    mq_unlink(QUEUE_NAME);

    return NULL;
}

static void * queue_client(void *parc) {
    mqd_t mq;
    char buffer[MAX_SIZE];

    mq = mq_open(QUEUE_NAME, O_RDWR);
    printf("mq_send : %d
", mq);

    int count = 0;
    while(1) {
        snprintf(buffer, sizeof(buffer), "MESSAGE %d", count++);

        printf("CLIENT: Send message... 
");
        mq_send(mq, buffer, MAX_SIZE+1, 0);

        fflush(stdout);
        tm_thread_sleep(1);
    }

    mq_close(mq);
    return NULL;
}

int main() {

    pthread_t client, server;
    printf("Start...
");
    pthread_create(&server, NULL, &queue_server, NULL);
    pthread_create(&client, NULL, &queue_client, NULL);
    pthread_join(server, NULL);
    pthread_join(client, NULL);
    printf("Done...
");
    return (EXIT_SUCCESS);
}

输出:

Start... 

mq_receive :3

SERVER: None

mq_send : -1

CLIENT: Send message...

SERVER: None

CLIENT: Send message...

SERVER: None
答案

这里的问题是,你发送的缓冲区大小超过了。

    mq_send(mq, buffer, MAX_SIZE+1, 0);

它应该是

    mq_send(mq, buffer, MAX_SIZE, 0);

如果你已经验证了mq_send的返回值,你可能已经弄明白了。它回来了

define EMSGSIZE 90 /* Message too long */ error.

修改后,我能够得到以下输出。

Start...
mq_send : 4
mq_receive : 3
CLIENT: Send message...
SERVER: Received message: MESSAGE 0
CLIENT: Send message...
SERVER: Received message: MESSAGE 1
CLIENT: Send message...
SERVER: Received message: MESSAGE 2
CLIENT: Send message...
SERVER: Received message: MESSAGE 3

找到完整的代码如下。

#include <fcntl.h>
#include <mqueue.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#define QUEUE_NAME  "/testqueue"
#define MAX_SIZE    1024

static void * queue_server(void *pars);
static void * queue_client(void *parc);

static void * queue_server(void *pars) {
mqd_t mq;
unsigned int sender;
int bytes_read;

struct mq_attr attr;
char buffer[MAX_SIZE];

attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = MAX_SIZE;
attr.mq_curmsgs = 0;

mq = mq_open(QUEUE_NAME, O_RDONLY | O_NONBLOCK | O_CREAT, 0666, &attr);
printf("mq_receive : %d
",mq);
        printf("SERVER: None %d %d 
", errno, bytes_read);
memset(buffer, 0x00, sizeof(buffer));
mq_unlink (QUEUE_NAME);
while(1) {

    bytes_read = mq_receive(mq, buffer, MAX_SIZE, &sender);
    if(bytes_read >= 0) {
        printf("SERVER: Received message: %s
", buffer);
    } else {
        printf("SERVER: None %d %d 
", errno, bytes_read);
    }

  //  fflush(stdout);
    sleep(1);
    }
mq_close(mq);
mq_unlink(QUEUE_NAME);

return NULL;
}
static void * queue_client(void *parc) {
mqd_t mq;
char buffer[MAX_SIZE];


struct mq_attr attr;

attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = MAX_SIZE;
attr.mq_curmsgs = 0;



mq = mq_open(QUEUE_NAME, O_CREAT|O_WRONLY|O_NONBLOCK , 0666,&attr);
printf("mq_send : %d
",mq);

int count = 0;
while(1) {
    snprintf(buffer, sizeof(buffer), "MESSAGE %d", count++);

    printf("CLIENT: Send message... 
");
    int bytes_read = mq_send(mq, buffer, MAX_SIZE, 0);
        printf("CLIENT: send %d %d 
", errno, bytes_read);

//    fflush(stdout);
    sleep(1);
}
mq_close(mq);
return NULL;
}

int main() {

pthread_t client, server;
printf("Start...
");
pthread_create(&server, NULL, &queue_server, NULL);
pthread_create(&client, NULL, &queue_client, NULL);
pthread_join(server, NULL);
pthread_join(client, NULL);
printf("Done...
");
return (EXIT_SUCCESS);
}

以上是关于Posix消息队列接收/发送/打开不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

使用 POSIX 消息队列进行进程内通信

POSIX 中的消息队列

POSIX消息队列

POSIX消息队列

POSIX 消息队列通过内核空间?

Swift 接收 javascript 消息不起作用