On 16 Dec 2004 20:38:29 -0500, David Bolen <[EMAIL PROTECTED]> wrote:
>Scott Robinson <[EMAIL PROTECTED]> 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) -- http://mail.python.org/mailman/listinfo/python-list