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
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.