Python 实现多线程编程需要借助于 threading 模块,而threading模块中最核心的内容是Thread这个类。我们要创建Thread对象,然后让它们运行,每个Thread对象代表一个线程,在每个线程中,我们可以让程序处理不同的任务,这就是多线程编程。
创建Thread对象有两种手段:
1.直接创建Thread对象
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
参数类型:
target:需要线程去执行的方法名,这是一个必须要传递的参数
import threading
import time
def test():
for i in range(5):
print('test',i)
time.sleep(1)
thread=threading.Thread(target=test)
# target=test,表示线程thread在start之后,要执行的方法为test()方法
thread.start()
for i in range(5):
print('main',i)
time.sleep(1)
上面代码很简单,在主线程上打印 5 次,在一个子线程上打印 5 次。
输出为:
2.自定义类继承Thread类
直接看代码:
import threading
# 这是一个包,即一段python程序
import time
from threading import current_thread
# current_thread类可以获取当前线程的引用,一般都是在没有线程对象又需要获得线程信息时通过current_thread获取当前代码段所在线程的引用。其中current_thread.getName()方法可以获得当前运行线程的名称。
class myThread(threading.Thread):
def run(self):
print(current_thread().getName(),'start')
print('run')
print(current_thread().getName(), 'stop')
t1=myThread()
# 自定义类对象
t1.start()
t1.join()
# 注意:join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程在终止,
print(current_thread().getName(),'end')
输出为:
3.生产者和消费者问题
首先构建一个队列:
import queue
q=queue.Queue()
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
输出为:
然后开始着手配置生产者与消费者的进程:
from queue import Queue
from threading import Thread
from threading import current_thread
import random
import time
queue=Queue(5)
# 直接创建一个长度为5的空队列
class ProducerThread(Thread):
def run(self):
name=current_thread().getName()
nums=range(100)
# Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。
global queue
# 若想在函数内部对函数外的变量进行操作,就需要在函数内部声明其为global。在本程序中,将queue前加global,表示可以在函数体内对外部队列进行操作。
while True:
num=random.choice(nums)
# choice() 方法返回一个列表,元组或字符串的随机项,在本程序中,返回的是1-100之间的随机数字。
queue.put(num)
print('生产者 %s 生产了数据 %s'%(name,num))
t=random.randint(1,3)
time.sleep(t)
print('生产者 %s 睡眠了%s 秒'%(name,t))
class ConsumerThread(Thread):
def run(self):
name=current_thread().getName()
global queue
while True:
num=queue.get()
queue.task_done()
# 线程等待与同步的数据包
print('消费者 %s 消耗了数据 %s'%(name,num))
t=random.randint(1,5)
time.sleep(t)
print('生产者 %s 睡眠了%s秒' %(name,t))
p1=ProducerThread(name='p1')
p1.start()
c1=ConsumerThread(name='c1')
c1.start()
c2=ConsumerThread(name='c1')
c2.start()
输出为(可以一直运行下去,截取了部分截图):