python编程
首发于python编程
python多线程之从Thread类继承

python多线程之从Thread类继承

上一篇文章实现多线程的方式是

  • 创建函数
  • Thread函数创建进程,将要运行的函数传入其中

本文我们讲另一种实现多线程的方式————从threading.Thread类继承出一个新类,主要实现__init__run方法

首先我们来看一个最简单的例子,只实现了run方法

import time
import threading

class MyThread(threading.Thread):

    def run(self):
        time.sleep(1)
        a = 1 + 1
        print(a)

for _ in range(5):
    th = MyThread()
    th.start()

解读如下

  • 定义一个类,继承threading.Thread类,里面只需要定义run方法
  • run方法相当于之前传入Thread的那个函数,注意只能用run这个名字,不用显式调用,线程start()时会自动调用run
  • 创建类的实例时不需要传入参数,得到的结果就可以调用start join等方法
  • 上一篇文章提过Thread对象可以调用start join run等方法,其实当时调用start就是自动调用了run。这里只不过是在新类中重写了run方法,线程调用start时就会自动执行这个run

上面每次运行的run都是一样的,真正使用时很少会这样用,有时会需要传入一些区别性的参数,这就需要定义类的__init__了,我们来看下面的例子

import threading
import requests
from bs4 import BeautifulSoup

class MyThread(threading.Thread):

    def __init__(self, i):
        threading.Thread.__init__(self)
        self.i = i

    def run(self):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(self.i*25)
        r = requests.get(url)
        soup = BeautifulSoup(r.content, 'html.parser')
        lis = soup.find('ol', class_='grid_view').find_all('li')
        for li in lis:
            title = li.find('span', class_="title").text
            print(title)

for i in range(10):
    th = MyThread(i)
    th.start()

上面代码实现10个线程抓取豆瓣top250网站10页的电影名,通过__init__将循环信息传到类之中。

上一篇文章不使用类来使用多线程时,讲了Thread函数的参数,Thread对象的方法和一些可以直接调用的变量,这里我们分别讲一下

  • Thread函数的参数。初始化线程时传入一些参数,这里也可以在__init__中定义
  • Thread对象的方法。这里可以用self直接调用这些方法
  • threading.activeCount()等直接调用的变量。在这里依然可以调用

所以用类的方法不会有任何限制,下面来看一个例子

import time
import threading

class MyThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name # 这样就相当于Thread中的name参数了
        
    def run(self):
        a = 1 + 1
        print(threading.currentThread().name)
        time.sleep(1)
        print(self.name)
        time.sleep(1)
        print(self.is_alive()) # 未显式定义过就可以直接用
        

t = time.time()

ths = [MyThread('thread {}'.format(i)) for i in range(3)]

for th in ths:
    th.start()

print(threading.activeCount())
for th in ths:
    th.join()
    
print(time.time() - t)

返回结果如下

thread 0
thread 1
thread 2
4
thread 0
thread 2
thread 1
True
True
True
2.0039498805999756

使用类继承方式其实还有另一种形式。

之前是直接用run定义计算函数,如果已经有一个计算函数,也可以用传入的方式而不是改写成run

import threading
import requests
from bs4 import BeautifulSoup

def gettitle(page):
    url = 'https://movie.douban.com/top250?start={}&filter='.format(page*25)
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html.parser')
    lis = soup.find('ol', class_='grid_view').find_all('li')
    for li in lis:
        title = li.find('span', class_="title").text
        print(title)

class MyThread(threading.Thread):

    def __init__(self, target, **args):
        threading.Thread.__init__(self)
        self.target = target
        self.args = args

    def run(self):
        self.target(**self.args)

for i in range(10):
    th = MyThread(gettitle, page = i)
    th.start()

专栏信息

专栏主页:python编程

专栏目录:目录

版本说明:软件及包版本说明

编辑于 2018-05-07

文章被以下专栏收录