阻塞,直到事件完成

阻塞,直到事件完成

问题描述:

gcc 4.4.2 c89阻塞,直到事件完成

我有一个功能,必须运行(config_relays)。它调用一个名为set_relay的API函数,然后代码必须等待,直到set_relay事件完成。 set_relay是任何异步调用。

void run_processes() 
{ 
    switch() 
    { 
     case EV_RELAY_SET: 
     break; 
    } 
} 


void config_relays() 
{ 
    set_relay(); 

    /* Wait until EV_RELAY_SET has fired */ 
    /* Cannot do init_relay until set_relay event has fired - has to block here */ 
    init_relay(); 
} 

我想我可以把init_relay()中的开关。但是,该事件用于其他事情,而不仅仅用于初始化中继。我真的很想处理config_relays函数中的所有内容。

在C#中,您可以使用autoreset来完成此操作。 C有这样的事情吗?

非常感谢任何建议,

正如Anders写的,有条件的等待是解决方案。在POSIX Thread API中,您可以使用pthread_cond_wait和互斥量。这是很容易,以下模式工作:

 
int ready_flag = 0; 
pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 

void wait_ready() 
{ 
    pthread_mutex_lock(&ready_mutex); 
    while(!ready_flag) { 
    pthread_cond_wait(&ready_cond, &ready_mutex); 
    } 
    pthread_mutex_unlock(&ready_mutex); 
} 


void set_ready(int ready) 
{ 
    pthread_mutex_lock(&ready_mutex); 
    ready_flag = ready; 

    pthread_cond_signal(&ready_cond); 
// or using pthread_cond_broadcast(&ready_cond); 

    pthread_mutex_unlock(&ready_mutex); 

} 

pthread_cond_signal会和调用pthread_cond_broadcast是,如果对国旗多个线程等待设置,pthread_cond_signal会只释放一个线程,但广播释放所有线程之间的差异。

不是说围绕您的条件创建的while循环取决于您,您可以测试多个条件或做任何你想要的。代码模式确保您的测试是在受保护的变量进行,使得比赛条件会不会引起例如

问题

while(resource_a_busy && resource_b_busy) ...

是其中两个资源状态必须由互斥体进行保护的一个典型问题。

cond_wait可以从循环中删除,但是它会将wait_ready转换为消耗CPU的轮询循环,pthread_wait_cond不消耗任何CPU。

有迹象表明,提供一个Win32一样,让喜欢在Win32 API事件的顶部API一个phread上并行线程的顶部以及图书馆API移植库,后来被称为Pthreads-w32

这取决于你使用的是什么的线程库和异步方法是如何被调用。如果您在Windows上,则可以使用Windows API中的自动重置事件。请参阅CreateEvent API。如果你在Unix/Linux上,你可以在pthreads中查看条件变量。不幸的是,pthreads没有自动重置事件,因为它们很难以无竞争条件的方式使用。

当选择您的等待策略时,您还必须考虑异步调用是如何完成的。它是否在另一个线程上?它是通过信号处理完成的吗?其他一些“借用”主线程的异步机制?如果通过“借用”主线程完成调用,则必须确保您的等待策略不会阻止线程被用于执行异步调用。

1)您可以使用特定于操作系统的API(如createEvent或pthread条件变量)等待并在set_relay()完成时发出信号。

2)轮询方式。定期轮询以查看set_relay()已完成,否则,休眠几秒钟并重试。

+0

我编译在Redhat。所以会使用pthreads。选项2,我正在考虑在一个while循环中进行轮询,并且在事件中有一个条件集(全局变量),并测试这个条件是否成立。 1)我对选项1感兴趣。 – ant2009 2010-03-31 09:25:00

+1

好,投票方法不好,非常糟糕。永远不要设计一个带有投票/休眠方案的系统。它可能成为瓶颈...... – Ernelli 2010-03-31 09:35:14