多线程下的奇怪问题,很奇怪,大家看看。
dzbjet
|
1#
dzbjet 发表于 2007-06-30 17:35
多线程下的奇怪问题,很奇怪,大家看看。
[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/env python
# -*- coding: gb2312 -*- import threading def flush_p(string): import sys print string sys.stdout.flush() class mythread(threading.Thread): def __init__(self): threading.Thread.__init__(self, group=None) self.__cond = threading.Condition(threading.Lock()) self.__task = None def run(self): while True: self.__cond.acquire() while self.__task == None: self.__cond.wait() if isinstance(self.__task, exit_task): self.__task = None self.__cond.release() flush_p('xxxxxxxxxxxxxxxxxxxx') break try: print 'b run' self.__task.run() print 'a run' except: pass finally: flush_p('mythread: b none') self.__task = None flush_p('mythread: a none') self.__cond.release() def set(self, task): self.__cond.acquire() self.__task = task self.__cond.notify() self.__cond.release() def terminate(self): flush_p('mythread: b terminate') self.set(exit_task()) flush_p('mythread: a terminate') self.join() class task: def __init__(self, callfunc=None, calldata=None): self.__callfunc = callfunc self.__calldata = calldata def run(self): if self.__callfunc != None: if self.__calldata != None: self.__callfunc(self.__calldata) else: self.__callfunc() else: pass class exit_task(task): pass class wrapper: def __init__(self): def worker(): print 'worker' self.myt = mythread() self.myt.start() self.myt.set(task(worker)) def __del__(self): self.myt.terminate() self.myt.join() def __Fuck(self): print 'fuck' def main(): w = wrapper() if __name__ == '__main__': main() 以上代码没有问题,但是如果把 self.myt.set(task(worker) 的worker换成类的成员函数(self.myt.set(task(self.__Fuck)) ),就会出现阻塞在self.__task = None 这块,一直不返回, 为什么? 即以下代码会阻塞:
[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/env python
# -*- coding: gb2312 -*- import threading def flush_p(string): import sys print string sys.stdout.flush() class mythread(threading.Thread): def __init__(self): threading.Thread.__init__(self, group=None) self.__cond = threading.Condition(threading.Lock()) self.__task = None def run(self): while True: self.__cond.acquire() while self.__task == None: self.__cond.wait() if isinstance(self.__task, exit_task): self.__task = None self.__cond.release() flush_p('xxxxxxxxxxxxxxxxxxxx') break try: print 'b run' self.__task.run() print 'a run' except: pass finally: flush_p('mythread: b none') self.__task = None flush_p('mythread: a none') self.__cond.release() def set(self, task): self.__cond.acquire() self.__task = task self.__cond.notify() self.__cond.release() def terminate(self): flush_p('mythread: b terminate') self.set(exit_task()) flush_p('mythread: a terminate') self.join() class task: def __init__(self, callfunc=None, calldata=None): self.__callfunc = callfunc self.__calldata = calldata def run(self): if self.__callfunc != None: if self.__calldata != None: self.__callfunc(self.__calldata) else: self.__callfunc() else: pass class exit_task(task): pass class wrapper: def __init__(self): def worker(): print 'worker' self.myt = mythread() self.myt.start() self.myt.set(task(self.__Fuck)) def __del__(self): self.myt.terminate() self.myt.join() def __Fuck(self): print 'fuck' def main(): w = wrapper() if __name__ == '__main__': main() |