gcc 4.4.3 c89
我有一个在单独的线程中运行的事件循环。
我的设计如下所示,只是示例代码以帮助解释。
我需要以某种方式等待初始化完成才能调用get_device_params。
我在调用get_device_params之前确实放了3秒钟,但我真的不想阻止。
非常感谢任何建议,
void* process_events(void *data)
{
switch(event_type)
{
case EVT_INITIALIZED:
/* Device is now initialized */
break;
}
}
int main(void)
{
/* Create and start thread and process incoming events */
process_events();
/* Initialize device */
initialize_device();
/* Get device parameters */
/* However, I cannot run this code until initialization is complete */
get_device_params();
return 0;
}
答案 0 :(得分:4)
如果这个单独的线程是一个POSIX线程(即你在典型的UNIX平台上),那么你可以使用pthread条件变量。
您在等待线程中调用pthread_cond_wait()
。当init线程完成其工作时,您调用pthread_cond_signal()
。在我看来,这是一种在另一个线程中等待初始化的规范方法。
答案 1 :(得分:2)
我需要以某种方式等待初始化完成才能调用get_device_params。
由于你在process_events()
中显然有某种FSM,并且它为什么要在一个单独的线程中运行,你不应该从主线程与设备做任何事情。
换句话说,逻辑上,如果设备初始化get_device_params();
,我应该将EVT_INITIALIZED
的调用放在FSM内部,我认为这是initialize_device()
触发的。
或者,您可以创建第二个FSM(可能在另一个线程中)并在完成自己的处理后让process_events()
(第一个FSM)转发EVT_INITIALIZED
事件到第二个FSM。 (或initialize_device()
可以同时将事件发送给两个FSM。)
对我来说,似乎(根据您发布的稀缺代码)您的问题是您尝试将顺序代码与基于事件的代码混合。经验法则:在基于事件/ FSM的应用程序中,所有代码都应在FSM内运行,由事件触发;应该没有可以在FSM之外运行的代码。
答案 2 :(得分:1)
如果是我,我可能会使用障碍物。在main中,您可以调用pthread_barrier_init,表示您有2个线程。然后,在主调用pthread_barrier_wait中,在调用设备初始化函数后等待初始化的屏障。最后,在设备线程中,初始化设备后,可以在同一个屏障上调用pthread_barrier_wait,当两个线程都在等待时,屏障将被满足,因此两个线程都将继续。我发现障碍比条件变量更容易使用,但我确信这是一个偏好问题。