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有这样的东西。
非常感谢任何建议,
答案 0 :(得分:2)
正如安德斯所写,条件等待是解决方案。在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。
有一些移植库在pthreads之上提供类似于Win32的API,以及在Win32事件API之上提供类似API的phread的库,后者称为Pthreads-w32
答案 1 :(得分:1)
这取决于您使用的线程库以及如何调用异步方法。如果您使用的是Windows,则可以使用Windows API中的自动重置事件。请参阅CreateEvent
API。如果你在unix / linux上,你可以在pthreads中查看条件变量。不幸的是,pthreads没有自动重置事件,因为它们很难以无竞争条件的方式使用。
在选择等待策略时,您还必须考虑异步调用的完成方式。它在另一个线程上吗?它是通过信号处理完成的吗?其他一些“借用”主线程的异步机制?如果通过“借用”主线程完成调用,则必须确保等待策略不会阻止线程用于执行异步调用。
答案 2 :(得分:1)
1)您可以使用特定于OS的API(如createEvent或pthread条件变量)等待,并在set_relay()完成时发出信号。
2)轮询方法。定期轮询以查看set_relay()已完成,否则请休眠几秒钟并重试。