LINUX.ORG.RU

Как прибить recvfrom по таймауту в многопоточном коде?


0

0

Проблема в следующем:
...
rc = recvfrom(...); // Блокирует тред
...

Я знаю решения проблемы, но вот как в тредах их применять...
1) alarm
Просто делаем alarm(TIMEOUT) и ловим errno==EINTR.
Это работает хорошо в однопоточных программах, но возникает вопрос -
какой тред получит SIGALARM? Да и как вообще обрабатывать сигналы
в тредах, ведь action'ы вроде задаются на процесс, а на тред
только маски.
2) MSG_DONTWAIT
Задать неблокирующее чтение и ловить EAGAIN.
При этом вызывать нужно в цикле и делать какую-то (хоть даже малую)
задержку.
Возникает вопрос - как делать задержку?
Ведь select(1,0,0,0,&timeout) в тредах вроде тоже вызывать нельзя
(not thread safe).
А задержка с дискретом в секунду меня не устроит.
3) select
Not thread safe. 
4) SO_SNDTIMEO / SO_RCVTIMEO
После вот таких описаний желание использовать пропадает:

SO_{SND,RCV}TIMEO are probably the most widely
unimplemented, or strangely/incompatibly implemented, of all
common sockopts in existence... Basically, in short, NEVER
try to use them for anything... ;-)

Короче - как _грамотно_ решается подобная задача?

Спасибо!

Я юзал select в многопоточном коде. Нигде про Not thread safe не слышал.

Kpoxman ★★
()

> какой тред получит SIGALARM?

я так понимаю у каждого треда свой id - кому пошлёшь тот и получит :-) (обработчики - да - одинаковы для всех тредов, а маски разные)

Mr_Nobody
()


1. pthread_kill(2) из другого потока, в котором крутится собственн обработчик таймера.
2. флаг O_NONBLOCK + select(2). про thread unsafe - это миф. даже не представляю, откуда он взялся.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> про thread unsafe - это миф. даже не представляю, откуда он взялся

Может из GTK? Или может имеется в виду async signal safe ф-ции?

Mr_Nobody
()

selectom мониторишь не появилось ли чего прочитать из сокета (там и задается таймаут).
если появилось, то читаешь.
все работает не блокируя треды.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.