8-1 如何使用多线程
Posted 石中玉smulngy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8-1 如何使用多线程相关的知识,希望对你有一定的参考价值。
>>> help(Thread) Help on class Thread in module threading: class Thread(_Verbose) | A class that represents a thread of control. | | This class can be safely subclassed in a limited fashion. | | Method resolution order: | Thread | _Verbose | __builtin__.object | | Methods defined here: | | __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None) | This constructor should always be called with keyword arguments. Arguments are: | | *group* should be None; reserved for future extension when a ThreadGroup | class is implemented. | | *target* is the callable object to be invoked by the run() | method. Defaults to None, meaning nothing is called. | | *name* is the thread name. By default, a unique name is constructed of | the form "Thread-N" where N is a small decimal number. | | *args* is the argument tuple for the target invocation. Defaults to (). | | *kwargs* is a dictionary of keyword arguments for the target | invocation. Defaults to {}. | | If a subclass overrides the constructor, it must make sure to invoke | the base class constructor (Thread.__init__()) before doing anything | else to the thread.
方法一:直接创建线程时执行
from threading import Thread from time import sleep def handle(sid): print (\'Download...(%d)\' %sid) #模拟下载过程 sleep(2) print (\'Convert to...(%d)\' %sid) #模拟转换过程 t = Thread(target= handle, args=(1,)) #创建线程,参数target线程运行的函数,args参数是一个元组,是target指向函数的参数 t.start() #启动线程 print(\'main thread\')
输出结果:
Download...(1)main thread
Convert to...(1)
打印‘Download’和‘Convet’中间打印的’main thread’说明线程启动后,主线程先运行完了,此时子线程仍然在运行,
正常都要在启动的子线程都运行完成后,主线程再执行完,这时要在start()之后增加 join()等待子线程执行完,主线程再继续执行
t.start()
t.join() #是一个阻塞函数,子线程不运行完,join就不返回。
print(\'main thread\')
输出结果:
Download...(1)
Convert to...(1)
main thread
方法二:创建一个线程类来封装数据
# -*- coding: cp936 -*- from threading import Thread from time import sleep def handle(sid): print (\'Download...(%d)\' %sid) sleep(2) print (\'Convert to...(%d)\' %sid) """ t = Thread(target= handle, args=(1,)) t.start() t.join() """ class MyThread(Thread): #自定义线程类 def __init__(self,sid): #Thread.__init__(self) super(MyThread,self).__init__() #必须调用 父类的构造器 这是py2的语法,py3是super().__init__() self.sid = sid #使用类,能够更好的封装数据 def run(self): #新建程序的入口点,和target类似 handle(self.sid) #更常见的做法是将handle也做为这个类的方法 t = MyThread(1) t.start() t.join() print(\'main thread\')
结果输出:
Download...(1)
Convert to...(1)
main thread
三、完成10个线程下载和转换
# -*- coding: cp936 -*- from threading import Thread from time import sleep def handle(sid): print (\'Download...(%d)\' %sid) sleep(2) print (\'Convert to...(%d)\' %sid) """ t = Thread(target= handle, args=(1,)) t.start() t.join() """ class MyThread(Thread): #自定义线程类 def __init__(self,sid): #Thread.__init__(self) super(MyThread,self).__init__() #必须调用 父类的构造器 self.sid = sid #使用类,能够更好的封装数据 def run(self): #新建程序的入口点,和target类似 handle(self.sid) #更常见的做法是将handle也做为这个类的方法 threads = [] #创建一个空列表,将创建的线程添加到这个线程列表中去 for i in xrange(1,11): t = MyThread(i) threads.append(t) t.start() for x in threads: #迭代线程列表,等待所有的子线程 x.join() print(\'main thread\')
输出结果:
Download...(1)Download...(4)Download...(2)Download...(3)Download...(5)Download...(6)Download...(7)Download...(8)Download...(9)Download...(10)
Convert to...(4)Convert to...(1)Convert to...(2)Convert to...(5)Convert to...(3)Convert to...(6)Convert to...(7)
Convert to...(9)
Convert to...(8)Convert to...(10)
main thread
IO操作和CPU密集型操作,IO操作特点下载传输速度慢,此时多几个CPU提高效率不明显。CPU密集型操作,执行速度快,CPU多了执行效率高。但python多线程 不适合执行CPU密集型操作,因为python中有全局解释器锁GIL,导致当前只有一个线程能被python解释器执行。Python多线程不是真正意义上的并发。与C语言的多线程不同。这种类似于供销模式类型,更适合用协程来操作
以上是关于8-1 如何使用多线程的主要内容,如果未能解决你的问题,请参考以下文章