Что делать при ожидании окончания мероприятия - PullRequest
1 голос
/ 16 сентября 2010

gcc 4.4.3 c89

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

Мой дизайн такой, как показано ниже, просто пример кода, чтобы помочь объяснить.

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

Я поставил usleep на 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;
}

Ответы [ 3 ]

4 голосов
/ 16 сентября 2010

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

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

2 голосов
/ 16 сентября 2010

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

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

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

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

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

1 голос
/ 18 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...