Waitforsingleobject и waitformultipleobjects эквивалентны в linux
я переношу applciation из windows в linux. Я сталкиваюсь с проблемой в отношении WaitForSingleObject и WaitForMultipleObjects интерфейсы.
в моем приложении я создаю несколько потоков, где все потоки ждут событий из родительского процесса или периодически запускаются каждые t секунд.
Я проверил pthread_cond_timedwait , но мы должны указать абсолютное время для этого.
как я могу реализовать это в Unix?
4 ответов
палкой pthread_cond_timedwait и использовать clock_gettime . Например:
оберните его в функцию, если вы хотите.
UPDATE: дополнение ответа на основе наших комментариев.
POSIX не имеет ни одного API для ожидания «всех типов» событий/объектов, как это делает Windows. У каждого свои функции. Самый простой способ уведомить поток о завершении-использовать атомарные переменные / операции. Например:
Другой альтернативой является отправка запроса на отмену с помощью pthread_cancel . Отменяемый поток должен был вызвать pthread_cleanup_push для регистрации любого необходимого обработчика очистки. Эти обработчики вызываются в обратном порядке, в котором они были зарегистрированы. Никогда не звоните pthread_exit из обработчика очистки, потому что это неопределенное поведение. Состояние выхода отмененного потока — PTHREAD_CANCELED . Если вы выбираете эту альтернативу, я рекомендую вам читать в основном о точках и типах отмены.
и последнее, но не менее, называя pthread_join будет делать текущий блок потока, пока поток, переданный аргументом, не завершится. В качестве бонуса, вы получите статус выхода потока.
для чего это стоит, мы (NeoSmart Technologies) только что выпустили библиотеку с открытым исходным кодом (MIT licensed) под названием pevents, который реализует WIN32 ручной и автоматический сброс событий на POSIX и включает в себя клоны WaitForSingleObject и WaitForMultipleObjects.
хотя я лично советую вам использовать многопоточные и сигнальные парадигмы POSIX при кодировании на машинах POSIX, pevents дает вам другой выбор, если вам это нужно.
Я понимаю, что это старый вопрос, но для всех, кто натыкается на него, этот источник предполагает, что pthread_join() делает то же самое, что WaitForSingleObject():
WaitForMultipleObjects = ?
Эта прекрасная виндовая функция, которая позволяла мирно завершать поток: одному или нескольким событиям поток выполнял заданые действия, а по другому можно было мирно завершиться. В линуксе такого обнаружить не удалось: pthread_cond_wait позволяет ждать только одного события. В свое время меня учили, что за функции типа pthread_cancel обычно выдирают руки из ж. Так как можно красиво сделать так, чтобы в нужный момент поток завершился сам?
Re: WaitForMultipleObjects = ?
Это зависит от того, что твой поток делает. Если это, к примеру, сервер.. то надо к нему приконектиться и послать shutdown request. Для того, чтобы подождать его завершение использовать симафор (pthread_cond_wait).
Сложно сказать, не зная алгоритма =) Если у тебя прекрасно все получалось с WaitForMultipleObjects то придумай сам какой-то класс, который будет ждать сигнала от нескольких семафоров.
Re: WaitForMultipleObjects = ?
в принципе, можно select/poll заиспользовать
Re: WaitForMultipleObjects = ?
Я бы использовал ACE (framework, который proactor или task) — там есть реализация WFMO и весьма приближающаяся к ней PT версия.
Re: WaitForMultipleObjects = ?
Если подробнее, нужно pthread_cond_waitdtime() для нескольких pthread_cond_t по схеме «или» («и»-то сделать элементарно) Работать это должно так: while(1) < int result = pthread_multi_cond_wait(. ); switch(result) < case 0: doSomething1(); break; case 1: doSomething2(); break; . case n: return; >> По событию n поток мирно завершается сам. Мне, в принципе, нужно только два события — одно для выполнения работы, другое — для выхода. Использовать select не получится — он для файлового ввода-вывода.
Re: WaitForMultipleObjects = ?
> Я бы использовал ACE Что-то это больно крутое. Для моей задачи — перебор.
Re: WaitForMultipleObjects = ?
Как вариант можно использовать pthread_cond_wait в чистом виде как он есть, НО! перед g_cond_broadcast выставлять некую переменную с типом описывающее происходящее, чтобы рабочий поток уже сам решил как ему поступить дальше. Ориентировочно это может выглядеть так:
typedef enum
GMutex * work_mutex; GCond * work_cond;
//гдето в потоке которому нужно запросить выполнение работы: g_mutex_lock(work_mutex); condtype=SOMEJOB; g_cond_broadcast(work_cond); g_mutex_unlock(work_mutex);
//в случае необходимого завершения потока: g_mutex_lock(work_mutex); condtype=SHUTDOWN; g_cond_broadcast(work_cond); g_mutex_unlock(work_mutex); pthread_join(. ); //здесь поток worktread уже явно завершен
WaitForSingleObject and WaitForMultipleObjects equivalent in Linux?
I am migrating an applciation from windows to linux. I am facing problem with respect to WaitForSingleObject and WaitForMultipleObjects interfaces.
In my application I spawn multiple threads where all threads wait for events from parent process or periodically run for every t seconds.
I have checked pthread_cond_timedwait , but we have to specify absolute time for this.
How can I implement this in Unix?
4 Answers 4
Stick to pthread_cond_timedwait and use clock_gettime . For example:
Wrap it in a function if you wish.
UPDATE: complementing the answer based on our comments.
POSIX doesn’t have a single API to wait for «all types» of events/objects as Windows does. Each one has its own functions. The simplest way to notify a thread for termination is using atomic variables/operations. For example:
Another alternative is to send a cancellation request using pthread_cancel . The thread being cancelled must have called pthread_cleanup_push to register any necessary cleanup handler. These handlers are invoked in the reverse order they were registered. Never call pthread_exit from a cleanup handler, because it’s undefined behaviour. The exit status of a cancelled thread is PTHREAD_CANCELED . If you opt for this alternative, I recommend you to read mainly about cancellation points and types.
And last but not least, calling pthread_join will make the current thread block until the thread passed by argument terminates. As bonus, you’ll get the thread’s exit status.
Подскажите Аналог WaitForSingleObject(hThread,0)
Здравствуй, Всемогущий all!
Пишу с использованием Posix threads. Проблема в следующем — в моем приложении основной поток создает дополнительный поток, и ему (основному потоку) иногда нужно проверять — а не закончил ли еще дополнительный поток свою работу?, но чтобы при этом основной поток не останавливал свою работу, то есть pthread_join, увы не подходит. В windows-программировании эту проблему легко решить с помощью вызова WaitForSingleObject(hAdditionalThread,0) — а как это можно сделать в Unix?, и по возможности posix-ными функциями (вроде pthread_tryjoin_np годится, но она непосиксовая 🙁 )?
Подскажите кто знает пожалуйста — ибо решение в виде заведения атомарной или защищенной mutex’ом переменной для статуса потока и последующая работа через нее все же абсолютно не прельщает.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
В pthreads вроде нет аналога. Либо сделайте pthread_detach, чтобы не джойнить его совсем, либо вызовите join при завершиении программы.
Если все же надо джойнить поток в середине работы, то самый простейший вариант — вызвать pthread_getschedparam если случится ошибка, то поток, вероятнее всего, мертв и можно сделать join.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Смотрите в сторону подписки на события, таким образом, при асинхронном исполнении основной поток должен обработать событие завершения вспомогательного. где-то так.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Вы имеете в виду с помощью функции pthread_getschedparam определять, не завершился ли поток? — то есть если поток завершился, то pthread_getschedparam вернет не 0?
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Будьте добры, напишите плиз названия функций подписки на события, чтобы мне понять в каком направлении копать
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
менять архитектуру приложения, сперва желательно почитать умные книжки [хотя бы Threads Primer].
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> менять архитектуру приложения, сперва желательно почитать умные >книжки [хотя бы Threads Primer].
Спасибо за совет, правда если все же подскажете название конкретной функции (которую я уже буду искать в умных книжках), то будет совсем здорово
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> Спасибо за совет, правда если все же подскажете название конкретной функции (которую я уже буду искать в умных книжках), то будет совсем здорово
если бы была такая функция её бы подсказали, чай не звери.
но проблема не в функции, проблема в дизайне.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> если бы была такая функция её бы подсказали, чай не звери. > но проблема не в функции, проблема в дизайне.
Вы имеете в виду, что мне стоит перепроектировать приложение так, чтобы не приходилось на ходу определять в основном потоке — не закончилась ли работа дополнительного?
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> Вы имеете в виду, что мне стоит перепроектировать приложение так, чтобы не приходилось на ходу определять в основном потоке — не закончилась ли работа дополнительного?
именно. запустил поток[и]? хорошо. найди в себе силы дождаться их завершения (pthread_join).
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Увы, не очень вижу способа, как решить мою задачу без проверки состояния потоков :(. Но это уже выходит за рамки поста. Большое спасибо всем за ответы, тему можно закрыть.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Вы имеете в виде, что если треда уже закончится к моменту вызова pthread_mutex_trylock, то функция вернет ошибку — и это может служить критерием того, работает ли поток?
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
hm. ну если автора вопроса устроит *try* aka периодический опрос, то тогда уж condvar+mutex. рабочий поток перед завершением взводит условную переменную, а родительский соответственно так или иначе проверяет её через pthread_cond_timedwait(). AFAIU проблема в том, что автор не хочет так делать, i.e. периодически опрашивать рабочей поток умер он уже или ещё нет?
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
но она, естественно, Linux специфичная
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> но она, естественно, Linux специфичная
а чем она поможет в данной ситуации? вопрос ведь не в том, как пристрелить дочерний поток — он и так сам завершается — а в том, как бы поудобнее об этом узнать в родительском без блокировки на pthread_join() на неопределённое время.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
Открыть один глобальный pipe. Родитель слушает, каждый завершившийся поток пишет свой ид.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
обработку сигнала никто не отменял
перед pthread_exit() в дочернем потоке вызываем tkill() и в родительском ловим соответствующий сигнал после чего выполняем требуемые действия
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> обработку сигнала никто не отменял. перед pthread_exit() в дочернем потоке вызываем tkill() и в родительском ловим соответствующий сигнал после чего выполняем требуемые действия
обработка сигналов в многопоточной программе — это не столь тривиальная тема :-/ родительский поток готов к тому, что его могут прервать в произвольном месте? и что он будет после этого делать? бежать по внутреннему списку запущенных потоков и смотреть опять же по своим флажкам, какой из потоков ещё жив а какой нет? а смысл?
вопрос в том, зачем автору нужно асинхронно завершать дочерние потоки и что он хочет этим добиться. в зависимости от ответа можно советовать ту или иную схему организации приложения. просто так же гадать на кофейной гуще IMHO смысла мало.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
>вопрос в том, зачем автору нужно асинхронно завершать дочерние >потоки и что он хочет этим добиться. в зависимости от ответа можно >советовать ту или иную схему организации приложения. просто так же >гадать на кофейной гуще IMHO смысла мало.
Да не нужно асинхронно завершать — нужно знать — отработался ли еще дочерний поток или нет. В двух словах приложение — что-то вроде коллектора трафика — приложение принимает траффик по udp и пишет его на лету в базу mysql без индексов, тип таблицы myISAM. По истечении, допустим, данные накопились уже — запускаю индексирование данных в отдельном потоке (на лету с индексами писать нереально, поток слишком сильный). А когда подойдет очередная порция данных через час мне обязательно нужно узнать — закончилось ли индексирование или продолжается пока. В windows-варианте приложения использую WaitForSingleObject, а здесь вот не нашел решения, почему и пришел на форум.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> Да не нужно асинхронно завершать — нужно знать — отработался ли еще дочерний поток или нет. В двух словах приложение — что-то вроде коллектора трафика — приложение принимает траффик по udp и пишет его на лету в базу mysql без индексов, тип таблицы myISAM. По истечении, допустим, данные накопились уже — запускаю индексирование данных в отдельном потоке (на лету с индексами писать нереально, поток слишком сильный). А когда подойдет очередная порция данных через час мне обязательно нужно узнать — закончилось ли индексирование или продолжается пока. В windows-варианте приложения использую WaitForSingleObject, а здесь вот не нашел решения, почему и пришел на форум.
ну и замечательно. есть два потока, основной и индексирующий. основной поток создаёт mutex+cond, запускает индексирующий и возвращается к своим делам. индексирующий поток какое-то время работает, после чего по окончанию взводит переменную (pthread_cond_signal) и завершается, переходя в состояние зомби. основной поток в какой-то момент времени, когда ему понадобится узнать, завершилось ли уже индексирование или нет, проверяет состояние cond. он это может делать полностью синхронно через pthread_cond_wait aka блокируясь на переменной, или же асинхронно aka периодически проверяя её состояние через pthread_cond_timedwait. что конкретно выбрать зависит от приложения и его логики. anyway, в какой-то момент времени, когда основной поток таки смог дождаться переменной — wait вернул success — он вызывает pthread_join на дочерний поток для подчистки ресурсов [бо теперь это уже по логики приложения неблокирующая операция] и дальше идёт своей дорогой зная, что индексирование точно завершилось бо рабочий поток ему об этом явно сообщил.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
ps: да, если у вас основной поток что-то пишет в базу, не вздумайте использовать tkill()/pthread_kill() — libmysqlclient весьма неоднозначно относится к сигналам и прерывание себя, любимой.
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
pps: WaitForSingleObject() с нулевым таймаутом на хендл потока — это аналог функций pthread_tryjoin() или pthread_timedjoin() которых нет в POSIX API и, по всей видимости, не будет. но поведение WFSO без особых проблем эмулируется через существующее API посредством штатных механизмов синхронизации как мьютекс и механизмов оповещения о событиях как condition variable. при желании в заданном контексте можно сделать и аналог WaitForMultipleObjects().
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
>pps: WaitForSingleObject() с нулевым таймаутом на хендл потока — это >аналог функций pthread_tryjoin() или pthread_timedjoin() которых нет >в POSIX API и, по всей видимости, не будет. но поведение WFSO без >особых проблем эмулируется через существующее API посредством >штатных механизмов синхронизации как мьютекс и механизмов оповещения >о событиях как condition variable. при желании в заданном контексте >можно сделать и аналог WaitForMultipleObjects().
Если без особых проблем, то может напишете примерно как именно :-[?
Re: Подскажите Аналог WaitForSingleObject(hThread,0)
> ну и замечательно. есть два потока, основной и индексирующий.