LINUX.ORG.RU

select на сокете, получение «протухших» данных

 ,


0

2

приветы

допустим, есть два процесса - п1 и п2. Связаны между собой через unix доменный сокет. п1 пишет в п2 некоторые данные и ждет результат Р1 выполнения, который п2 должен закинуть в этот сокет. п1 ждет этот результат с помощью select с таймаутом.

В итоге, по истечении таймаута п1 выполняет некоторую другую работу (а в этот момент допустим п2 все таки запишет результат Р1 в сокет) и потребуется допустим еще раз отправить уже какие то другие данные потоку п2 и получить от п2 уже результат Р2 обработки новых данных.

Что будет когда п1 вызовет select с таймаутом во второй раз:

- 1) select сразу вернет управление и recv прочитает «протухшие» данные из сокета, то есть Р1? - 2) что прочитает п2 из сокета - то что он туда записал Р1 или новые данные от п1 (допустим чтение идет одинаковыми размерами)?

И вопрос еще - как это побороть? может есть какой то устоявшийся механизм или дело просто в доработке протокола обмена между п1 и п2?

вопрос 2 в итоге к тупому вопросу можно свести - если процесс п2 записал в сокет 16 байт, но никто этот сокет не прочитал, и процесс п1 записал в сокет еще 16 байт, то потом если процесс п2 будет считать куском 16 байт - какие данные он получит?



Последнее исправление: elmir_k (всего исправлений: 1)

Ничего не понятно.

select сработает если есть невычитанные данные. Если в системный буфер пришло 20 байт, ты вычитал 10 и не стал читать дальше, то следующий select сработает сразу, и recv вернет еще 10 байт.

PPP328 ★★★★★
()

вы теоретик ? практик набросает тесты, проверит, разберется.

anonymous
()

Связывайте процессы не «через сокет», а через пару сокетов, соединённых друг с другом для передачи данных.

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

Не исключено. Возможно, что и вы их путаете. Это не страшно, - материя-то тонкая.

Sorcerer ★★★★★
()

Данные не пишутся в сокет, данные пишутся через сокет в принимающий процесс. Когда один пишет, его блокирует пока на второй стороне не прочитают.

Селект ничего не пишет и ничего не читает. Он лишь говорит есть ли заблокированный на записи процесс на другом конце.

У epoll кстати есть разные режимы примерно камательно того что ты спрашиваешь. Почитай мануалы по епол для разнообразия.

redixin ★★★★
()

Для SOCK_STREAM очерёдность гарантируется. На то он и stream. Для SOCK_DGRAM — нет.

i-rinat ★★★★★
()

В итоге получилось следующее решение.

Так как select возвращает количество оставшихся секунд до истечения таймера, то селект можно завернуть в цикл и в цикле проверять «свежесть» данных из сокета. Для определения «свежести» каждая порция данных снабжается уникальным идентификатором, то есть пара запрос-ответ будет иметь уникальный идентификатор, и если отправив запрос мы получаем «старый» ответ, то его просто игнорируем и заводим опять select до полного истечения таймаута.

 while (tv.tv_sec != 0) {
 
 rc = select (socketd + 1, &readfds, NULL, NULL, &tv);
 //читаем данные из сокета и проверям на "свежесть"
//если данные старые, то опять попадаем на селект уже с меньшим значением таймаута
}

про epoll - прочитаю, кажется он таки может делать тоже самое своими способами

elmir_k
() автор топика

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

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