is socket thread safe?
Carl J. Van Arsdall
cvanarsdall at mvista.com
Thu Feb 16 11:52:56 EST 2006
Bryan Olson wrote:
> Carl J. Van Arsdall wrote:
>
>> Steve Horsley wrote:
>>
>>
>>> e2wugui at gmail.com wrote:
>>>
>>>
>>>
>>>> thread1:
>>>> while 1:
>>>> buf = s.read()
>>>> process(buf)
>>>>
>>>> thread2:
>>>> while 1:
>>>> buf = getdata()
>>>> s.write(buf)
>>>>
>>> It is safe, but watch out for this gotcha: If thread B calls s.close()
>>> while thread A is blocked in s.read(), thread A will never return from
>>> the read. My preferred solution is to set socket timeout to a few
>>> seconds, and loop checking a status flag so I know when to quit.
>>>
>
> Certainly one needs timeouts to avoid hanging should the remote
> side stop. Sockets don't have a read() method, and hanging on
> recv() doesn't seem to have anything to do with close().
>
> I didn't find any definitive doc, so I tested using Python
> sockets on Linux (Debian/Ubuntu current) and WinXP. A recv()
> started before the close() will block/return just as if
> close() were never called. The close() neither triggers recv()
> to abort, nor prevents it from receiving data and detecting
> shutdown.
>
>
>
>> I think a better thing would be to use something like a condition object
>> to tie the two threads together and not use any polling loops.
>>
>> i.e. consumer goes to sleep while data buffer is empty, producer
>> produces and signals condition object, consumer wakes up and consumes.
>>
>
> I can infer two producer-consumer relationships from the example,
> but they don't allow a condition object; the writer's consumer and
> the reader's producer are on the remote end of the socket. The
> socket will already handle the blocking and wake-up.
>
>
>> To take this a step further, you have a status flag that is set to
>> something like QUIT or CONSUME and when the condition is triggered wake
>> up, then examine the status flag to determine if the consumer should
>> then quit, consume, or whatever else you'd want your consumer thread to do.
>>
>
> What problem are you trying to solve? Normal socket sending, receiving,
> and shutdown discipline work fine. When the writer is done writing, it
> should call sock.shutdown(socket.SHUT_WR). When the reader gets zero
> bytes from recv(nonzero), that means the remote end has finished
> writing, so the reader may call sock.shutdown(socket.SHUT_RD).
>
Doh! I read the word threads and got carried away not even realizing
sockets. Well, looks like today i'll just have to remember to drink my
coffee
:-D
-c
--
Carl J. Van Arsdall
cvanarsdall at mvista.com
Build and Release
MontaVista Software
More information about the Python-list
mailing list