Python多线程基础

示例

使用该threading模块,可以通过创建新的执行线程threading.Thread并为其分配执行功能来启动新的执行线程:

import threading

def foo():
  print "你好线程!"

my_thread = threading.Thread(target=foo)

该target参数引用要运行的函数(或可调用对象)。直到start在Thread对象上调用该线程后,该线程才会开始执行。

启动线程

my_thread.start() # prints '你好线程!'

现在my_thread已经运行并终止了,start再次调用将产生一个RuntimeError。如果您想将线程作为守护程序运行,则在调用之前传递daemon=Truekwarg或设置my_thread.daemon为,会使您作为守护程序在后台静默运行。Truestart()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):
    # 魔术功能,需要所有页面才能执行
    if not q.full():
        raise ValueError
    else:
        print("完成编译!")

threads = []
for page_num in range(20):
     t = Thread(target=requests.get, args=(page_num,))
     t.start()
     threads.append(t)

# 接下来,加入所有线程以确保所有线程在运行之前都已完成
#我们继续。join()是一个阻塞调用(除非另行指定,否则使用 
# 调用加入时,kwarg阻止= False)
for t in threads:
    t.join()

# 由于所有线程均已完成,因此立即调用compile()
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方法自动调用Thread类的run方法。
    # 打印“主程序继续在前台运行。”
    t.join()
    print("主程序继续在前台运行。")