C 多线程应用程序中的锁定和解锁
你好, 决定在多线程应用程序中需要在何处执行锁定和解锁 保持代码片段简短。我有一个全球渠道结构。i、 eC 多线程应用程序中的锁定和解锁,c,multithreading,C,Multithreading,你好, 决定在多线程应用程序中需要在何处执行锁定和解锁 保持代码片段简短。我有一个全球渠道结构。i、 e gcc (GCC) 4.1.2 c89 我有3个函数,它们使用API设置和处理其消息队列上的通道 apr_status_t set_ss7_channel_state(channel_t *channel) { /* API call to set channel - non-blocking ASYNC call that returns immediately w
gcc (GCC) 4.1.2
c89
我有3个函数,它们使用API设置和处理其消息队列上的通道
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);
}
我的主线程#1将调用此函数
typedef struct tag_channel channel_t;
struct tag_channel {....};
事件循环在生成的线程#2中启动。其他函数可能会触发相同的通道购买,将该通道放入消息队列
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调用的进程通道
因此,基本上,对于单个通道,呼叫是这样工作的:
apr_status_t channel_process(channel)
{
/* process channel here based on the event
/* lock channel */
/* do some processing */
/* unlock channel */
}
我想知道我是否需要阻止通道结构,因为此通道上可能有其他事件?
我在channel_进程上设置了阻塞
非常感谢您的建议,这将取决于频道结构的内容以及setChanState和waitev的具体交付方式 如果tag_通道不包含引用(例如指针、文件描述符或任何其他间接的引用),并且setChanState/waitev将它的副本传递给thread2(例如通过管道),那么您就是在有效地实现参与者模型,并接近实现通信顺序过程(这更好),并且不需要进一步锁定
否则,您必须使用互斥体来保护通道结构本身或它间接引用的内容。是的,您必须阻止通道结构。关键是,线程1能够在线程2处理最后一个事件时覆盖通道结构的内容(以及与之关联的数据)
有多种方法可以同步此过程。可以通过阻塞线程1直到线程2完成,也可以简单地在结构中添加一个关键部分。或者将渠道结构构建为一个要处理的作业链。我看不出您打算如何在此处使用多个线程。此外,您的问题也不可能作为答案回答是的,因为“本频道的其他事件”这不是简单的发生,而是其他一些代码做了一些影响通道的事情的结果。如果不知道更多,就不可能回答。我要说的是,不仅当tag_通道确实包含引用时,你必须保护结构。即使它是一组相关的整数值,如果生产者thread将在使用者线程仍在运行时开始更改值。@JUnitx,您的注释是在不知道标记通道的内容或其用途的情况下编写的。原始问题引用了消息队列,完全可能使用了参与者模型(甚至更好的CSP)(可能是意外使用的)根据原始海报。如果你不知道这些是什么,我建议你查找它们,它们很有用。是的,你是对的。我忽略了tag_频道的内容-或者更好:我没有对它的内容做任何假设。因为没有关于这个主题的信息,我认为在这里做假设是不安全的。这也不清楚她说OP实现CSP或者他是否想要实现演员模型。此外,还不清楚OP是否将频道信息传递给线程2,而线程1仍然保留对它的引用。鉴于这些不确定性,我在你的帖子中添加了一条评论,因为我不认为你的答案适合“所有情况”@junix,我也没有。我的文章的最后一段“否则你必须使用互斥来保护通道结构本身,或者它间接引用的东西”到底是怎么回事在任何情况下都不能覆盖你自己的贡献?似乎你文章中的最后一句话逃过了我的注意。很抱歉。但我可以建议你重新安排省略保护的条件吗?因为在我看来,省略保护的主要论点是,副本已经交付,而不是没有引用在结构中有es。我将单独处理这个方面,因为有不同的方法来处理它。(例如,适当的序列化)
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