0
gcc (GCC) 4.1.2
c89

你好,

决定在多线程应用程序中我需要在哪里进行锁定和解锁。

保持代码片段简短。我有一个全球渠道结构。IE

typedef struct tag_channel channel_t;
struct tag_channel {....};

我有 3 个函数使用 API 来设置和处理其消息队列上的通道。

我的主线程 #1 将调用此函数

apr_status_t set_ss7_channel_state(channel_t *channel)
{
    /* API call to set channel - non-blocking ASYNC call that returns immediately
       wait for event in evt_loop */
    setChanState(channel);
}

事件循环在生成的线程 #2 中开始。其他功能可以触发相同的频道购买,将频道放入消息队列。

static void* APR_THREAD_FUNC evt_loop(apr_thread_t *thd, void *data)
{
    while(is_looping) {
        /* Get event and channel from message API message queue */      
        waitevt();
        if(channel_process(channel) != TRUE) {
            /* clean up */      
        }   
    }
}

从线程 #2 调用的进程通道

apr_status_t channel_process(channel)
{
    /* process channel here based on the event
    /* lock channel */
    /* do some processing */
    /* unlock channel */
}

因此,对于单个通道,基本上调用是这样工作的:

1) setChanState(channel) thread #1 -> puts channel on an API message queue
2) evt_loop(...) thread #2 will retrieve the event and the channel structure
3) process_channel(channel) will process the channel on thread #2

我想知道我是否需要阻止频道结构,因为该频道上可能还有其他事件?我已经对 channel_process 设置了阻塞。

非常感谢您的任何建议,

4

2 回答 2

1

是的,您必须阻止通道结构。关键是您的线程#1 能够覆盖通道结构的内容,而线程#2 正在处理最后一个事件(以及与之关联的数据)。

有多种同步方式。通过阻塞线程#1 直到线程#2 完成,或者您可以简单地向结构中添加某种临界区。或者,您将渠道结构构建为要处理的工作链。

于 2013-07-15T05:29:45.433 回答
-1

这将取决于通道结构的内容以及 setChanState 和 waitev 传递它的确切方式。

如果 tag_channel 不包含引用(例如指针、文件描述符或其他任何间接的东西)并且 setChanState/waitev 将它的副本传递给 thread2(例如通过管道),那么您正在有效地实现 Actor 模型,并且接近实现通信顺序进程(甚至更好),并且不需要进一步的锁定。

否则,您将必须使用互斥锁来保护通道结构本身或它间接引用的事物。

于 2013-07-15T05:29:13.077 回答