LINUX.ORG.RU

threads & signals


0

0
Здравствуйте. Процессу надо время от времени перечитывать файлик. Ну стандарно это делается через alarm() и затем обработка сигнала SIGALARM. А как это будет выглядеть в случае потоков? Какой из них будет остановлен для обработки сигнала? Или все сразу ? В принципе мне без большой разницы, главное чтобы после обработки сигнала все продолжили работать, где остановились (и если кто-то к примеру висел на семафоре, то там и остался)
anonymous
Хм.. хотя стандарт POSIX это как-то обговаривает помоему это нигде нормально не реализовывается, так что не особо надейся что сможешь угадать какой поток получит сигнал. лучше сделай все через pthread_mutex_* и pthread_cond_*... к примеру пусть один поток спит столько сколько надо времени, а потом сообщает через pthread_cond_t, тем кого это волнует. имхо это будет хорошее решение ))

подробности в манах и у Стивенса )

OxiD ★★★★
()
Ответ на: комментарий от OxiD
тяжеловатый у человека случай - подружить треды и сигналы.

я бы рекомендовал забить на сигналы и выделить один тред который будет в цикле спать на nanosleep и между паузами заниматся полезным трудом

cvv ★★★★★
()
Ответ на: комментарий от cvv
А может тебе вообще надо select-om/poll-om висеть на дескрипторе файла и перечитывать только при изменении??
cvv ★★★★★
()
а может можно отказатся от тредов и построить fsm?
Ex ★★
()
Ответ на: комментарий от cvv
> в цикле спать на nanosleep

Ха-ха. Бывший паскальщик? За такие методы надо отбирать право пользоваться компилятором.
logIN ☆
()
Ответ на: комментарий от cvv
> я бы рекомендовал забить на сигналы и выделить один тред который
> будет в цикле спать на nanosleep и между паузами заниматся полезным
> трудом

Угу... очень разумно... может книжки почитаешь?

Традиционный подход - все треды блокируют сигналы за исключением
одного треда, который ждет на sigwait() или sigtimedwait().

HTH
Onanim ★
()
Ответ на: комментарий от logIN
>> в цикле спать на nanosleep

>Ха-ха. Бывший паскальщик? За такие методы надо отбирать право пользоваться компилятором.

если ты знаеш толк в извращениях с sigalrm в тредах то не думай что здесь все такие.

cvv ★★★★★
()
Ответ на: комментарий от Onanim
>Угу... очень разумно... может книжки почитаешь?

>Традиционный подход - все треды блокируют сигналы за исключением одного треда, который ждет на sigwait() или sigtimedwait().

или pause().

да но sigalrm один и вполне его можно не поделить с какой нибуть либсишной функцией. кроме того это может быть крестом на масштабируемости в тот момент когда потребуется два независимых sigalrm.

cvv ★★★★★
()
Ответ на: комментарий от cvv
Ладно, я не очень силен в тредах и сигналах, но то приложение, которые я написал, корректно работает с потоками. Я вполне могу создать отдельный поток, который будет заниматься этим делом. Если так лучше сделать - то как лучше усыпить поток но некоторый период времени? Т.е. лучше сделать как предлагалось выше - все потоки игноярт сигнал, а один обрабатывает sigalarm и пока его жедт вызывает pause() ? А если другой поток (который заблокировал прием сигналов) висит в это время на poll(), на его это никак не повлияет ?
anonymous
()
Ответ на: комментарий от anonymous
>Я вполне могу создать отдельный поток, который будет заниматься этим делом.

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

>Если так лучше сделать - то как лучше усыпить поток но некоторый период времени? Т.е. лучше сделать как предлагалось выше - все потоки игноярт сигнал, а один обрабатывает sigalarm и пока его жедт вызывает pause() ?

если ты уверен что sigalrm больше никому не понадобится то так и сделай

>А если другой поток (который заблокировал прием сигналов) висит в это время на poll(), на его это никак не повлияет ?

никак

cvv ★★★★★
()
Ответ на: комментарий от anonymous
> Ладно, я не очень силен в тредах и сигналах...

Стой-стой, причем тут pause() ?

Смотри:

1. До создания тредов делаешь pthread_sigmask(SIG_BLOCK, &signal_set, NULL)
блокируя все сигналы. Создавамые позднее треды унаследуют эту маску.

2. В каком-либо треде (да хоть в main thread) крутишь в цикле
sigwait(&signal_set, &sig), где signal_set содержит интересующие тебя
сигналы. Как тока сигнал поступает - sigwait() выходит, сохраняя номер
сигнала в sig и ты его обрабатываешь. Не надо никакого pause().
Да, AFAIK можно сделать несколько тредов - обработчиков сигналов при
условии, что они ждут в своих signal_set непересекающиеся множества
сигналов.

HTH
Onanim ★
()
Ответ на: комментарий от cvv
> > sigwait(&signal_set, &sig)

> с какой версии ядра поддерживается эта штука?

Не знаю но вроде она была еще в LinuxThreads,
естественно испытывая все связанные с этим проблемы.
Короче man sigwait.
BTW есть еще sigsuspend(), чем-то похожий по смыслу.

HTH
Onanim ★
()
при посылке сигнала процессу будет выбран "произвольный"
поток. это, насколько мне известно, соответсвует POSIX.
для посылки сигнала потоку есть tkill(), но alarm() это
не тот случай.

а вот posix timers (timer_create) позволяют указать в
качестве получателя _поток_ - SIGEV_THREAD_ID.

ну или как Onanim правильно сказал про блокировку сигнала
во всех потоках кроме одного.

sigwait() реализован был еще в 2.4.
idle ★★★★★
()
Ответ на: комментарий от idle
> для посылки сигнала потоку есть tkill()

Ну если следовать POSIX то pthread_kill()
Onanim ★
()
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.