<div dir="ltr">Один сокет можно использовать в нескольких процессах, но у вас должен быть протокол, который это поддерживает. Системный вызов send позволяет отправлять цельные блоки данных так, чтобы они не перебивались в середине данными из другого процесса. Например, я вполне могу представить себе родительский процесс, который устанавливает соединение с получателем данных, запускает N детей, которые что-то вычисляют и сбрасывают результаты своей работы непосредственно в сокет. Если нужно отправлять запросы и получать ответы, то тут уже никак не проверить, кому из процессов достанется ответ, если они друг с другом не будут договариваться через какие-то механизмы синхронизации. Тогда дочерний процесс должен закрыть соединение и открыть своё новое, чтобы с тем же сервером общаться по отдельному соединению.</div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 8, 2015 at 1:59 PM Victor Efimov <<a href="mailto:victor@vsespb.ru">victor@vsespb.ru</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">8 сентября 2015 г., 14:52 пользователь Ilya Chesnokov<br>
<<a href="mailto:chesnokov.ilya@gmail.com" target="_blank">chesnokov.ilya@gmail.com</a>> написал:<br>
> 8 сентября 2015 г., 0:03 пользователь Victor Efimov <<a href="mailto:victor@vsespb.ru" target="_blank">victor@vsespb.ru</a>> написал:<br>
>> Я думаю имелось ввиду несколько другое. Примеры это DBI и CPAN Redis.<br>
><br>
> Ну да. Хотя в целом про TCP keepalive тоже интересная тема.<br>
><br>
>> 1) Прежде чем послать данные в сокет сделать следующее:<br>
>><br>
>>   if ($self->{pid} != $$) {<br>
>>     $self->connect;<br>
>>   }<br>
>><br>
>> (код из Redis.pm)<br>
>><br>
>> 2) В DESTROY, если он есть, делать деструкцию только если $self->{pid} == $$.<br>
>> Надо сказать, это нужно только в DBI, т.к. он в DESTROY посылает<br>
>> какие-то данные в сокет. В "обычных" клиентах не нужно. В Redis.pm<br>
>> нету.<br>
><br>
> В-общем, ключевой вопрос в том, можно ли использовать одно и то же<br>
> соединение в разных процессах, если я правильно понял.<br>
> Если нельзя, то первый подход используется, если нельзя, то второй -<br>
> не закрывать соединение в дочерних процессах, а только в родительском.<br>
<br>
По-моему одно и то же соединение в любом случае использовать нельзя.<br>
Учитывая что сценарий -<br>
это fork() про который мы не знаем зачем и почему он. Возможно до<br>
fork() кто-то использовал соединение, после fork()<br>
собирается использовать и в child и parent. В таком случае и child и<br>
parent будут писать в один сокет. Это всё равно что они по-очереди<br>
будут писать в сокет в одном процессе.<br>
<br>
А DESTROY в DBI имхо просто для того чтобы закрыть коннект, чтобы у<br>
mysql сервера не висели открытые коннекты<br>
<br>
><br>
>> 3) реконнект<br>
>><br>
>> 8 сентября 2015 г., 5:36 пользователь Eugen Konkov <<a href="mailto:kes-kes@yandex.ru" target="_blank">kes-kes@yandex.ru</a>> написал:<br>
>>> Здравствуйте, Ilya.<br>
>>><br>
>>> IC> Есть ли готовые модули для поддержания постоянного соединения с<br>
>>> IC> каким-либо сервером?<br>
>>> Обычное TCP соединение с keep-alive пакетами<br>
>>> <a href="http://habrahabr.ru/company/intersystems/blog/155565/" rel="noreferrer" target="_blank">http://habrahabr.ru/company/intersystems/blog/155565/</a><br>
>>> <a href="http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html" rel="noreferrer" target="_blank">http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html</a><br>
>>><br>
>>>>не закрывалось при уничтожении форка<br>
>>> Делаете управление соединениями в мастер процессе. Создали соединение или их pool и отдаёте fork'ам хендлы. Если будет один хендл, То нужно будер решить проблему, какому форку передавать пришедший ответ (Думаю будет проще если создавать хендл/fork)<br>
>>><br>
>>> Вы писали 7 сентября 2015 г., 12:18:21:<br>
>>><br>
>>> IC> Добрый день.<br>
>>><br>
>>> IC> Есть ли готовые модули для поддержания постоянного соединения с<br>
>>> IC> каким-либо сервером? Нужно для того, например, чтобы инициализировать<br>
>>> IC> соединение при старте веб-приложения и повторно использовать в форках,<br>
>>> IC> при этом чтобы оно не закрывалось при уничтожении форка, ну и заново<br>
>>> IC> соединялось при необходимости.<br>
>>><br>
>>> IC> В-общем, нужно что-то вроде той части DBI, которая отвечает за<br>
>>> IC> TCP-соединение, но без всего того, что связано непосредственно с<br>
>>> IC> базами данных.<br>
>>><br>
>>> IC> Да, и еще интересно, есть ли что-то подобное отдельно для AnyEvent::Handle.<br>
>>><br>
>>> IC> --<br>
>>> IC> Best regards,<br>
>>> IC> Ilya Chesnokov<br>
>>><br>
>>><br>
>>><br>
>>> --<br>
>>> С уважением,<br>
>>>  Eugen                          mailto:<a href="mailto:kes-kes@yandex.ru" target="_blank">kes-kes@yandex.ru</a><br>
>>><br>
>>> --<br>
>>> Moscow.pm mailing list<br>
>>> <a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org" rel="noreferrer" target="_blank">http://moscow.pm.org</a><br>
><br>
><br>
><br>
> --<br>
> Best regards,<br>
> Ilya Chesnokov<br>
--<br>
Moscow.pm mailing list<br>
<a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org" rel="noreferrer" target="_blank">http://moscow.pm.org</a><br>
</blockquote></div>