2012-12-21 162 views
2
gcc 4.7.2 
c89 
APR 1.4 

你好,消息队列多线程

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

目前,我只是测试,如果我按ctrl-c。它会将时间设置为假。所以这个消息将在我的信号处理程序中发送,以便在我的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"); 
} 

回答

1

设置上msgrcv标志参数(第5 PARM)以IPC_NOWAIT。这使 队列 接收非阻塞。

+0

谢谢,我确实尝试过,并没有奏效。我觉得我玩的代码太多了。但是,现在是它的工作。 – ant2009