Python 多线程

一、线程的使用

需导入模块: from threading import Thread

二、基本使用

 def fun1(arg1, v):
print(arg1) print('before')
t1 = Thread(target=fun1, args=('aaa',11,))
t1.start()
print('此线程名称:', t1.getName()) t2 = Thread(target=fun1, args=('bbb',22,))
t2.start()
print('此线程名称:', t2.getName()) print('after')

三、常用方法

  • start
  • getName()
  • setName()
  • isDaemon()
  • setDaemon()
  • join(timeout)
  • run()
 def fun2():
for i in range(100):
print(i)
time.sleep(1) print('start')
t1 = Thread(target=fun2)
print('是否守护线程:', t1.isDaemon()) #默认为False,自动执行
#设置为守护线程,不自动执行,主程序执行完则子线程不执行,
#主程序如果没执行完,则子线程随着主程序执行,直至主程序结束,子线程也跟着结束
t1.setDaemon(True)
t1.start()
print('after1')
print('after2')
print('after3')
time.sleep(10)
 def fun1():
for i in range(10):
print(i)
time.sleep(1) print('before')
t1 = Thread(target=fun1)
t1.start()
# t1.join() #主程序执行到join()这里后挺住开始执行子线程,子线程执行结束后主程序继续执行
t1.join(5) #最多等5秒,子线程最多执行5秒后主进程继续向下执行,主程序执行结束后,子线程继续执行 print('after')

四、自定义线程类

 class MyThread(Thread):
def run(self):
time.sleep(3)
print('我是线程')
Thread.run(self) #如果不加此句,则不会执行自定义线程中的函数 def Bar():
print('bar') t1 = MyThread(target=Bar)
t1.start()
print('over')

五、自定义线程类应用 -- 生产者消费者模型

 #!/usr/bin/env python
# -*- coding:utf-8 -*- from queue import Queue
from threading import Thread
import time
import random class Producer(Thread):
def __init__(self, name, queue):
'''
生产者初始化
:param name:生产者名称
:param queue:容器
'''
self.__Name = name
self.__Queue = queue
super(Producer, self).__init__() #调用父类构造方法 def run(self):
while True:
if self.__Queue.full():
time.sleep(random.randrange(5))
else:
self.__Queue.put('包子')
time.sleep(random.randrange(5))
print('%s %s 生产了一个包子' %(self.__Name, time.strftime('%Y-%m-%d %H:%M:%S')))
# Thread.run(self) class Customer(Thread):
def __init__(self, name, queue):
'''
消费者初始化
:param name:消费者名称
:param queue: 容器
'''
self.__Name = name
self.__Queue = queue
super(Customer, self).__init__() def run(self):
while True:
# print('qsize=',self.__Queue.qsize())
if self.__Queue.empty():
time.sleep(random.randrange(5))
else:
self.__Queue.get_nowait()
time.sleep(random.randrange(3))
print('%s %s 消费了一个包子,还剩%d个包子' %(self.__Name, time.strftime('%Y-%m-%d %H:%M:%S'), self.__Queue.qsize()))
# Thread.run(self) que = Queue(maxsize=100) # print(que.qsize()) liFu = Producer('李师傅', que)
liFu.start() zhangFu = Producer('张师傅', que)
zhangFu.start() wangFu = Producer('王师傅', que)
wangFu.start() for item in range(20):
name = '陈涛%d' %(item,)
temp = Customer(name, que)
temp.start() # print(que.qsize()) # print(que.qsize())
# que.put('1')
# que.put('2')
# print('empty: ', que.empty())
# print(que.qsize())
# que.get()
# que.get()
# print('empty: ', que.empty())

六、函数编程实现生产者消费者模型

 #!/usr/bin/env python
# -*- coding:utf-8 -*- import time
import threading
import random
import queue def Producer(name, que):
while True:
if que.qsize()<3:
que.put('包子')
print('%s 生产了一个包子' % name)
else:
print('还有3个包子')
time.sleep(random.randrange(2)) def Customer(name, que):
while True:
try:
que.get_nowait()
print('%s 消费了一个包子' % name)
except Exception:
print('没有包子了...')
time.sleep(random.randrange(3)) que = queue.Queue(100) xf1 = threading.Thread(target=Producer,args=('师傅1',que))
xf1.start()
xf2 = threading.Thread(target=Producer,args=('师傅2',que))
xf2.start() xli = threading.Thread(target=Customer,args=('小李',que))
xli.start()
xzh = threading.Thread(target=Customer,args=('小张',que))
xzh.start()

七、线程锁

 #!/usr/bin/evn python
# -*- coding:utf-8 -*- import threading
import time num = 0 def fun1(n):
time.sleep(1)
global num
lock.acquire() # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
num += 1
lock.release() #释放锁,对数据操作完后要把锁释放掉,在没有释放前,不可以再添加需要锁
# time.sleep(0.01) 如果还有sleep一会,则表示此时不需CPU处理,则下面的print就不会按顺序输出
print(num) #如果释放锁后直接print,则是CPU锁定刚结束,还占用着CPU,则会按顺序输出 lock = threading.Lock() #线程锁 for i in range(100):
t = threading.Thread(target=fun1, args=('n',))
t.start()

八、递归线程锁 #一般不常用

 #!/usr/bin/evn python
# -*- coding:utf-8 -*- import threading
import time num = 0
num2 = 0 def fun1(n):
time.sleep(1)
global num
global num2
lock.acquire() # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
num += 1
lock.acquire() #使用递归锁就可以在锁内嵌套锁
num2 += 1
lock.release() #使用递归锁必须要把请求道的锁这个释放
lock.release()
print(num, num2) lock = threading.RLock() #线程锁 for i in range(100):
t = threading.Thread(target=fun1, args=('n',))
t.start()

九、同时进行多个线程

 #!/usr/bin/evn python
# -*- coding:utf-8 -*- import threading
import time num = 0 def fun1(n):
time.sleep(1)
global num
samp.acquire() # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
num += 1
print(num)
samp.release() #释放锁,对数据操作完后要把锁释放掉,在没有释放前,不可以再添加需要锁 # lock = threading.Lock() #线程锁
samp = threading.BoundedSemaphore(5) #设置此锁最多同时可以几个进行进行数据修改 for i in range(200):
t = threading.Thread(target=fun1, args=('n',))
t.start()

十、线程间的信息交互

 #/usr/bin/env python
# -*- coding:utf-8 -*- import threading
import time def producer():
print('收银员等人来买包子')
event.wait() #等待消息变化,等待有进程执行set()返回True
event.clear() #等到set()变成True了,则恢复set()的状态 print('收银员:有人来买包子')
print('收银员:给他做一个包子')
time.sleep(3) print('收银员:给你包子')
event.set() def customer():
print('张三来买包子')
event.set() time.sleep(1)
print('张三:等待取包子') event.wait()
event.clear()
print('张三:谢谢') event = threading.Event() #线程间可以互通消息的变量 kf = threading.Thread(target=producer)
kf.start()
zs = threading.Thread(target=customer)
zs.start()
上一篇:mysql根据身份证信息来获取用户属性信息


下一篇:[Java] JSP笔记 - 自定义标签