gc如何在python中使用eventlet(greenlet)?

时间:2016-06-21 04:49:19

标签: python garbage-collection eventlet

我在下面的测试脚本中创建了一个corolocal.local,以查找corolocal.local中的元素何时被垃圾收集。但目前还不是很清楚。当第二个线程为其分配另一个值时,第一个线程中实例化的TL.it被垃圾收集。 但我徘徊谁在什么时候做了gc.collect(),是否与之相关 greenlet运行范围?我曾经发现有时会在mainloop greenlet中收集TL.it,有时会收集另一个greenlet,这会在我的程序中引起问题。例如,如果我在__del __()方法中执行hub.switch(),它将报告错误"无法从MAINLOOP切换到MAINLOOP"。

import gc
import threading
from eventlet import hubs
from eventlet import event
import greenlet

import eventlet
eventlet.monkey_patch(all=True)


class InsideLocal(object):
    def __init__(self, td):
        self.td = td

    def __del__(self):
        print("Current greenlet inside %s: %s" %
              (self.td, greenlet.getcurrent()))
        print("Got deleted inside %s" % self.td)


class OutSideLocal(object):
    def __init__(self, td):
        self.td = td

    def __del__(self):
        print("Current greenlet outside %s: %s" %
              (self.td, greenlet.getcurrent()))
        print("Got deleted outside %s" % self.td)

TL = threading.local()


def play_insidethread(td, e):
    global TL
    TL.it = InsideLocal(td)
    ot = OutSideLocal(td)
    e.wait()
    print("Quiting thread %s" % td)

print("====Starting first thread====")
e = event.Event()
gt = eventlet.spawn(play_insidethread, 'first', e)

print("Primary greenlet: %s" % hubs.get_hub().greenlet)

# try to trigger gc for objects inside corolocal.local
# but here failed.
print("====Stopping first thread====")
e.send()
eventlet.sleep(0)

print("====Deleting greenthread object====")
# failed again
del gt
eventlet.sleep(0)

# failed again.
print("====Doing gc manually====")
print("gc %s" % gc.collect())
eventlet.sleep(0)

print("====Multi thread test====")
# succeeded.
events = []
for i in range(3):
    e = event.Event()
    events.append(e)
    eventlet.spawn(play_insidethread, i, e)

for e in events:
    e.send()
    eventlet.sleep(1)

print("====Quiting test====")
quit = event.Event()
quit.wait()

输出:

====Starting first thread====
Primary greenlet: <greenlet.greenlet object at 0x8c32d0>
====Stopping first thread====
Quiting thread first
Current greenlet outside first: <eventlet.greenthread.GreenThread object at 0x8c3370>
Got deleted outside first
====Deleting greenthread object====
====Doing gc manually====
gc 0
====Multi thread test====
Current greenlet inside first: <eventlet.greenthread.GreenThread object at 0x8c3370>
Got deleted inside first
Quiting thread 0
Current greenlet outside 0: <eventlet.greenthread.GreenThread object at 0x8c3370>
Got deleted outside 0
Current greenlet inside 0: <eventlet.greenthread.GreenThread object at 0x8c3410>
Got deleted inside 0
Quiting thread 1
Current greenlet outside 1: <eventlet.greenthread.GreenThread object at 0x8c3410>
Got deleted outside 1
Current greenlet inside 1: <greenlet.greenlet object at 0x8c32d0>
Got deleted inside 1
Quiting thread 2
Current greenlet outside 2: <eventlet.greenthread.GreenThread object at 0x8c34b0>
Got deleted outside 2
====Quiting test====

编辑:

我已阅读this article,但我没有得到答案。根据该文章的内容,每次访问一个对象(创建,删除等)时,python解释器将尝试进行一次垃圾收集,并在必要时从内存中删除一些对象。这不能解释我的测试结果,实际上在threading.local()中的对象而不是threading.local()中的对象表现不同。不在threading.local()中的对象在mainloop运行时永远不会被删除,但是threading.local()中的对象会被删除。

0 个答案:

没有答案