多线程基础知识
使用 threading
模块,可以通过创建新的 threading.Thread
并为其分配执行的函数来启动新的执行线程:
import threading
def foo():
print "Hello threading!"
my_thread = threading.Thread(target=foo)
target
参数引用要运行的函数(或可调用对象)。在 Thread
对象上调用 start
之前,线程不会开始执行。
开始一个线程
my_thread.start() # prints 'Hello threading!'
现在 my_thread
已经运行并终止,再次调用 start
会产生一个 RuntimeError
。如果你想将你的线程作为一个守护进程运行,传递 daemon=True
kwarg,或者在调用 start()
之前将 my_thread.daemon
设置为 True
,会导致你的 Thread
作为守护进程在后台静默运行。
加入主题
如果你将一个大工作分成几个小工作并想要同时运行它们,但需要等待所有这些工作完成才能继续,Thread.join()
是你正在寻找的方法。
例如,假设你要下载网站的多个页面并将其编译为单个页面。你这样做:
import requests
from threading import Thread
from queue import Queue
q = Queue(maxsize=20)
def put_page_to_q(page_num):
q.put(requests.get('http://some-website.com/page_%s.html' % page_num)
def compile(q):
# magic function that needs all pages before being able to be executed
if not q.full():
raise ValueError
else:
print("Done compiling!")
threads = []
for page_num in range(20):
t = Thread(target=requests.get, args=(page_num,))
t.start()
threads.append(t)
# Next, join all threads to make sure all threads are done running before
# we continue. join() is a blocking call (unless specified otherwise using
# the kwarg blocking=False when calling join)
for t in threads:
t.join()
# Call compile() now, since all threads have completed
compile(q)
仔细看看 join()
如何工作可以在这里找到。
创建自定义线程类
使用 threading.Thread
类我们可以继承新的自定义 Thread 类。我们必须在子类中覆盖 run
方法。
from threading import Thread
import time
class Sleepy(Thread):
def run(self):
time.sleep(5)
print("Hello form Thread")
if __name__ == "__main__":
t = Sleepy()
t.start() # start method automatic call Thread class run method.
# print 'The main program continues to run in foreground.'
t.join()
print("The main program continues to run in the foreground.")