Socket being garbage collected too early
Scott Robinson
dscottr at bellatlantic.net
Fri Dec 17 19:16:27 EST 2004
On 16 Dec 2004 20:38:29 -0500, David Bolen <db3l at fitlinxx.com> wrote:
>Scott Robinson <dscottr at bellatlantic.net> writes:
>
>> I have been having trouble with the garbage collector and sockets.
>
>Are you actually getting errors or is this just theoretical?
>
>> Unfortunately, google keeps telling me that the problem is the garbage
>> collector ignoring dead (closed?) sockets instead of removing live
>> ones. My problem is
>>
>>
>> x.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>> do_stuff(x.sock)
>>
>>
>> def do_stuff(sock):
>> sock_list.append(sock)
>>
>> once do_stuff finishes, x.sock disappears, and I can only believe it
>> is being garbage collected.
>
>Can you clarify this? What do you mean by "x.sock" disappears? Are
>you getting a NameError later when trying to use "x.sock"?
>
>x.sock is just a name binding, so it is not really involved in garbage
>collection (GC applies to the objects to which names are bound).
>
>In this case, you need to include much more in the way of code (a
>fully running, but smallest possible, snippet of code would be best),
>since the above can be interpreted many ways. At the least, it's very
>important to include information about the namespace within which
>those two code snippets run if anyone is likely to be able to give you
>a good answer. Also, being very precise about the error condition you
>are experiencing (including actual error messages, tracebacks, etc...)
>is crucial.
>
>Is 'x' referencing a local or global object, and does that socket code
>occur within a method, a function, or what? Also, in do_stuff, where
>is sock_list defined? Is it local, global?
>
>If, as written, sock_list is a local name to do_stuff, then that
>binding is going to disappear when do_stuff completes, thus, the list
>to which it is bound will be destroyed, including all references to
>objects that the list may contain. So at that point, when you return
>from do_stuff, the only reference to the socket object will be in
>x.sock. But if 'x' is also local to the function/method where the
>call to do_stuff is, the name binding will be removed when the
>function/method returns, at which point there will be no references to
>the socket object, and yes, it will be destroyed.
>
>But if sock_list is global, and continues to exist when do_stuff
>completes, then the reference it contains to the socket will keep the
>socket object alive even if you remove the x.sock binding.
>
>-- David
(so much for Python being executable psuedocode).
It looks like I was completely wrong. The problem I ran into was not
checking into baseHTTPserver and looking for self.close_connection=1.
I am pretty sure this happened to me before, and I rewrote the code to
avoid sockets being closed after being referenced to a live object,
but I can't reproduce it.
Anyway, here is my debugged test rig. It works. Ignore it.
Scott
[test program follows]
import socket, thread, time
class sock_holder:
pass
HOST = '127.0.0.1'
PORT = 2004
def echo_server(port):
print "started at",port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, port))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.send(data)
conn.close()
def wait_and_speak(a):
time.sleep(5)
try:
a.sock.send("this is message 2")
except:
print "error on message 2"
try:
data = a.sock.recv(1024)
print data
except:
print "error recieving message 2"
a.sock.close()
def other_thread(a):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
thread.start_new(echo_server,(PORT,))
time.sleep(1)
s.connect((HOST,PORT ))
s.send('Hello, port 1')
data = s.recv(1024)
print data
a.sock=s
thread.start_new(wait_and_speak,(a,))
a=sock_holder()
thread.start_new(other_thread,(a,))
time.sleep(10)
More information about the Python-list
mailing list