2012-05-04 2 views
2

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

{ 
    mediaQueue->PushEvent(boost::bind(/* params are not important */)); 

    return 0; 
} 

mediaQueue является очередью сообщений и на PushEvent() называют поток уведомляются, что есть работа, подлежащая обработке. Потребительский поток просто выполняет функтор, созданный с помощью bind.

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

Таким образом, вопрос: Возможно ли, чтобы продюсер был прерван сразу после его нажатия на событие, но до его возвращения?

Мое исследование до сих пор заставляет меня думать, что это возможно, и я должен реализовать блокировку, но как вы относитесь к этому?

ответ

3

Планировщик может прервать вашу нить в любое время. Это не означает (обязательно) знать или заботиться о том, что делает ваша нить, когда ее время заканчивается. Если есть возможное состояние гонки, да, вы должны потратить время и усилия на правильную блокировку.

В вашем случае это достаточно легко. Просто подождите объекта, установленного в функции вызываемого абонента при возврате из вашей функции PushEvent.

+0

Да, это странное требование. Использование синхронного объекта для принудительного возврата производителя до того, как потребитель попадет в основную часть своего кода, несомненно, будет работать, как вы говорите, но, скорее всего, приведет к почти бесполезному изменению контекста, поскольку потребитель просыпается на очереди, а затем снова блокируется явным синхронным ожиданием :(Тем не менее, лучше всего (только?) решение для необоснованного запроса, так что +1. –

+1

@MartinJames: для этого есть правило. Если текущий (сломанный) код без синхронизации, похоже, работает, то потоки в настоящее время выполняются в «правильном» порядке случайно. Таким образом, синхронизация будет дешевой, потому что синхронизирующий объект будет выпущен до того, как его нужно будет приобрести в другом потоке. UB, когда изменения таймингов, для шанса двойного контекстного переключателя при изменении таймингов, очень много :-) –

+0

@Steve Jessop да, это точно моя точка. Код работает именно так, но я уверен, что это вызовет проблемы, как только оно начнет работать :) –

1

Да, это возможно. Нить может быть назначена практически в любое время.

Похоже, что что-то не так, если это имеет значение, когда выполняется заявление return 0;. Действительно ли это return, который должен выполняться перед функтором, или это что-то еще, что делает поток производителей?

+0

Да, это проблема дизайна, но, к сожалению, вне моего контроля. Он работает таким образом 1. Клиент отправляет запросы и ожидает синхронного подтверждения того, что принято 2. Сервер принимает вызов (через обратный вызов) и возвращает 0 или 1 3. Клиент ожидает асинхронного ответа на результат. Проблема в том, что если второй поток начинается до возврата, я могу отправить результат для задания, которое еще не подтверждено как принятое. –

+0

Похоже, что это согласование принятия того, что потребительский поток должен ждать, а не возврат кода, который вы показываете. –

+0

@tsurko - не понимаю. Почему вы не просто отправляете accept перед очередью задания во второй поток? –

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