2010-09-16 2 views
1

gcc 4.4.3 c89Что делать, если ожидание окончания события

У меня есть цикл событий, который запускается в отдельном потоке.

Мой дизайн выглядит следующим образом, просто пример кода, который поможет объяснить.

Мне нужно как-то дождаться завершения инициализации, прежде чем я смогу позвонить на get_device_params.

Я проспал в течение 3 секунд перед вызовом get_device_params, но я действительно не хочу блокировать.

Большое спасибо за любые предложения,

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

Почему вы не вызываете get_device_params() в цикле событий события EVT_INITIALIZED? –

+0

На какой платформе это работает? –

+0

@Paul. Существует некоторая дополнительная обработка, которая должна быть выполнена. Поэтому нельзя вызывать событие EVT_INITIALIZED. – ant2009

ответ

2

Мне нужно как-то дождаться завершения инициализации, прежде чем я смогу позвонить на get_device_params.

Так как вы, очевидно, имеют какую-то FSM внутри process_events(), и почему-либо работает в отдельном потоке, вы не должны делать ничего от основного потока с устройством.

Другими словами, по логике вещей, вызов к get_device_params(); должен быть помещен внутрь автомата, на том случае, если устройство инициализируется EVT_INITIALIZED, который я полагаю, это вызвано initialize_device().

В качестве альтернативы вы можете создать второй FSM (возможно, в другом потоке) и дать process_events() (первый FSM) после того, как он завершит свою собственную обработку, переместите событие EVT_INITIALIZED во второй FSM. (Или initialize_device() может отправить событие в оба FSM одновременно.)

Мне кажется, что из-за скудного кода вы обнаружили, что ваша проблема заключается в том, что вы пытаетесь смешать последовательный код с основанным на событии. Правило большого пальца: в приложении/на основе FSM весь код должен запускаться внутри FSM, инициируясь событием; не должно быть никакого кода, который может запускаться самостоятельно вне FSM.

4

Если это отдельный поток является POSIX поток (т.е. вы на типичной платформе UNIX), то вы можете использовать условные переменные нитей.

Вы вызываете pthread_cond_wait() в ожидании. Когда поток init завершит свою работу, вы вызываете pthread_cond_signal(). На мой взгляд, это канонический способ ждать инициализации в другом потоке.

1

Если бы это был я, я бы, вероятно, использовал барьер. В основном вы можете вызвать pthread_barrier_init, указав, что у вас есть 2 потока. Затем в главном вызове pthread_barrier_wait, чтобы ждать инициализированного барьера, после вызова функции инициализации устройства. Наконец, в потоке устройства после инициализации устройства вы можете вызвать pthread_barrier_wait на том же барьере, и когда оба потока ожидают, барьер будет удовлетворен, поэтому оба потока будут продолжены. Я нахожу барьеры проще в использовании, чем переменные условий, но я уверен, что это вопрос предпочтения.

Смежные вопросы