c - 使用多线程的消息队列

标签 c multithreading message-queue

gcc 4.7.2
c89
APR 1.4

你好,

我正在使用 APR 线程池、事件循环(轮询)和消息队列(msgget、msgsnd、msgrcv)。

目前,我只是在测试是否按 ctrl-c。它会将 while 设置为 false。因此,消息将在我的信号处理程序中发送,并在我的 while 循环中接收。

但是,msgrcv 似乎阻塞在我的事件循环中。所以我无法从我的库中获取任何其他事件。在我的事件循环中,我正在检查是否已收到消息。但是,我认为它会阻止等待消息。这将导致我的循环停止循环,并且我将无法从我的库中捕获任何事件。

这是我第一次使用消息队列。

这是我的代码,我只复制了相关部分,所以我删除了所有错误检查以保持简短。

目前我只是在测试我的事件循环是否可以从队列中接收消息,因此它可以停止循环。

非常感谢您的任何建议,

#define MSG_KEY 0001L
static int msg_id = 0;
static volatile apr_status_t is_looping = FALSE;

/* Wait for these message commands */
typedef enum tag_msg_cmd {END_LOOP, START_LOOP} msg_cmd_e;

/* message queue data */
typedef struct tag_msg_data msg_data_t;
struct tag_msg_data {
    long mtype;
    msg_cmd_e msg_cmd;
};

int main(void)
{
    /* Create message queue */
    msg_id = msgget(MSG_KEY, 0666 | IPC_CREAT);

    /* Create thread pool */
    has_error = apr_thread_pool_create(&thd_pool,
                                       init_threads,
                                       max_threads,
                                       mem_pool_app);

   /* Start event loop */
   LOG_CHECK(apr_thread_pool_schedule(thd_pool,
                                       (apr_thread_start_t)event_loop,
                                       NULL,
                                       0,
                                       NULL) == APR_SUCCESS, "Failed to schedule event loop");

    /* Pause until ctrl-c */
    pause();

    /* Destroy all memory pools and threading pools */
}

/* Poll for incoming events */
static apr_status_t event_loop(void)
{
    msg_data_t msg_data;
    int evt_id = 0;
    int msg_id = 0;

    /* Connect to the message queue */
    msg_id = msgget(MSG_KEY, 0644);
    assert(msg_id != -1 && "Failed to connect to the message queue");
    LOG_DEBUG("Connected to message queue with msg ID [ %d ]", msg_id);

    while(is_looping) {
        /* Under development - Process incoming event from shared library */
        /* evt_id = sr_waitevt(timeout_ms); */
        /* process_event(evt_id); */

        LOG_DEBUG("Looping....");

        /* Should not be blocking here, as I need to receive other events */
        msgrcv(msg_id, &msg_data, (sizeof msg_data) - (sizeof(long)), 2, 0);
        LOG_DEBUG("Waiting...");
        if(msg_data.msg_cmd == END_LOOP) {
            LOG_DEBUG("END_LOOP event queue message has been received");
            break;
        }
        sleep(1);
    }

    return 1;
}

/* Signal handler will terminated application on ctrl-c */
static void signal_handler(int sig)
{
    msg_data_t msg_data = {2,  END_LOOP};
    int rc = 0;

    rc = msgsnd(msg_id,
                &msg_data,
                (sizeof msg_data) - (sizeof(long)),
                IPC_NOWAIT);

    assert(rc == 0 && "Failed to send data to the message queue");
}

最佳答案

msgrcv(第 5 个参数)上的标志参数设置为 IPC_NOWAIT。这使得 queue 接收非阻塞。

关于c - 使用多线程的消息队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13983913/

相关文章:

C:Make Capital 功能的总线错误

C 将字符数组打印为浮点型

java - 并发 C++ 程序中的可见性

c++ - 在无限循环中使用或不使用 join() 方法

apache-kafka - Apache Kafka 和 Camel 之间的区别(代理与集成)

c - 线程并发

c - 在函数内部将静态变量声明为 extern 有什么用?

java - JAVA方法中的线程互斥

java - 如何使 Spring Integration HTTP outbound-channel-adapter 参与 Global Transaction

c - 消息队列(msgget - msgsnd - msgrcv)Linux - EIDRM