Rah*_*u86 1 python multithreading asynchronous with-statement
我是python中的一个菜鸟,试图理解线程模块.我正在使用python 2.7.python中with_statement的动机之一被赋予了代码模式
with threading.Lock():
//User defined function in a new thread
Run Code Online (Sandbox Code Playgroud)
我不确定我是否已正确理解它,但我最初的假设是这个代码应该获取一个锁定在mainthread上,一旦子线程完成就会释放.然而这个剧本
from __future__ import print_function
import threading
import time
import functools
#import contextlib
#Thread module for dealing with lower level thread operations.Thread is limited use Threading instead.
def timeit(fn):
'''Timeit function like this doesnot work with the thread calls'''
def wrapper(*args,**kwargs):
start = time.time()
fn(*args,**kwargs)
end = time.time()
threadID = ""
print ("Duration for func %s :%d\n"%(fn.__name__ +"_"+ threading.current_thread().name ,end-start))
return wrapper
exitFlag = 0
@timeit
def print_time(counter,delay):
while counter:
if exitFlag:
thread.exit()
time.sleep(delay)
print("%s : %s_%d"%(threading.current_thread().name,time.ctime(time.time()),counter))
counter -= 1
class Mythread(threading.Thread):
def __init__(self,threadID,name,counter,delay):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
self.delay = delay
def run(self):
print("Starting%s\n" % self.name)
print_time(self.counter, self.delay)
print("Exiting%s\n" % self.name)
if __name__ == '__main__':
'''
print_time(5, 1)
threadLock = threading.Lock()
threads = []
thread1 = Mythread(1,"Thread1",5,1)
thread2 = Mythread(2,"Thread2",5,2)
thread1.start()
thread2.start()
threads.append(thread1)
threads.append(thread2)
for t in threads:
t.join()
'''
thread1 = Mythread(1,"Thread1",5,1)
thread2 = Mythread(2,"Thread2",5,2)
lock = threading.Lock()
with lock:
thread1.start()
thread2.start()
print("Exiting main thread ")
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
StartingThread1
StartingThread2
Exiting main thread
Thread1 : Sat May 04 02:21:54 2013_5
Thread1 : Sat May 04 02:21:55 2013_4
Thread2 : Sat May 04 02:21:55 2013_5
Thread1 : Sat May 04 02:21:56 2013_3
Thread1 : Sat May 04 02:21:57 2013_2
Thread2 : Sat May 04 02:21:57 2013_4
Thread1 : Sat May 04 02:21:58 2013_1
Duration for func print_time_Thread1 :5
ExitingThread1
Thread2 : Sat May 04 02:21:59 2013_3
Thread2 : Sat May 04 02:22:01 2013_2
Thread2 : Sat May 04 02:22:03 2013_1
Duration for func print_time_Thread2 :10
ExitingThread2
Run Code Online (Sandbox Code Playgroud)
请帮助我理解为什么锁定不能像这样使用with_statement或者我完全误解了这个概念.我很困惑为什么我直接打印("退出主线程")甚至通过定义一个锁
你现有的lock基本上什么都不做 没有其他线程可以引用它,因此它不可能导致任何人阻止任何地方.它唯一可能做的就是浪费几微秒.所以这:
lock = threading.Lock()
with lock:
thread1.start()
thread2.start()
Run Code Online (Sandbox Code Playgroud)
......几乎相当于:
time.sleep(0.001)
thread1.start()
thread2.start()
Run Code Online (Sandbox Code Playgroud)
而且我很确定这不是你想要的.
如果要强制线程按顺序运行,最简单的方法是不使用线程.
或者,如果必须使用线程,只需等待一个完成,然后再开始下一个:
thread1 = Mythread(1,"Thread1",5,1)
thread2 = Mythread(2,"Thread2",5,2)
thread1.start()
thread1.join()
thread2.start()
thread2.join()
Run Code Online (Sandbox Code Playgroud)
如果你想让线程自己序列化,没有外界的任何帮助,你必须给他们一个他们可以共享的锁.例如:
class Mythread(threading.Thread):
def __init__(self,threadID,name,counter,delay,lock):
threading.Thread.__init__(self)
self.lock = lock
# ...
def run(self):
with self.lock:
# ...
Run Code Online (Sandbox Code Playgroud)
现在,给他们打电话:
lock = threading.Lock()
thread1 = Mythread(1,"Thread1",5,1, lock)
thread2 = Mythread(2,"Thread2",5,2, lock)
thread1.start()
thread2.start()
# ...
thread1.join()
thread2.join()
Run Code Online (Sandbox Code Playgroud)
现在,当每个线程启动时,它将尝试获取锁定.一个会成功,另一个会阻塞,直到第一个完成锁定(通过退出其with声明).
如果你不想序列化线程,你只需要主线程等待所有其他线程的完成......你需要的就是join.这正是join为了什么.没有必要添加任何其他内容.
如果你真的想要,你可以守护线程并等待同步对象.我想不出一个简单的方法来做一个锁定,但它应该很容易用a BoundedSemaphore或a Condition(虽然你必须等待条件两次).但这是一件非常愚蠢的事情,所以我不确定你为什么这么想.