27 线程
1 线程模块
import threading
from time import sleep
def download(n):
images = ['girl.jpg', 'boy.jpg', 'man.jpg']
for image in images:
print('正在下载:', image)
sleep(n)
print('下载{}成功!'.format(image))
def listenMusic():
musics = ['大碗宽面', '土耳其冰淇淋', '烤面筋', '烤馒头片']
for music in musics:
sleep(0.5)
print('正在听{}歌!'.format(music))
if __name__ == '__main__':
t = threading.Thread(target=download, name='aa', args=(1,))
t.start()
t1 = threading.Thread(target=listenMusic, name='aa')
t1.start()
2 全局解释器锁 GIL
进程:计算密集型
线程:耗时操作型 IO操作(文件读写)
import threading
ticket = 100000000
def run1():
global ticket
for i in range(10000000):
ticket -= 1
def run2():
global ticket
for i in range(10000000):
ticket -= 1
if __name__ == "__main__":
th1 = threading.Thread(target=run1, name="th1")
th2 = threading.Thread(target=run2, name="th2")
th1.start()
th2.start()
th1.join()
th2.join()
print('money:', ticket)
--------------------------------------------------------------------------------------
import threading
ticket = 100000000
lock = threading.Lock()
def run1():
global ticket
lock.acquire()
for i in range(10000000):
ticket -= 1
lock.release()
def run2():
global ticket
lock.acquire()
for i in range(10000000):
ticket -= 1
lock.release()
if __name__ == "__main__":
th1 = threading.Thread(target=run1, name="th1")
th2 = threading.Thread(target=run2, name="th2")
th1.start()
th2.start()
th1.join()
th2.join()
print('money:', ticket)
3 死锁
'''
开发过程中使用线程,在线程间共享多个资源的时候,
如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
尽管死锁很少发生,但一旦发生就会造成应用的停止响应,程序不做任何事情。
避免死锁:
解决:
1. 重构代码
2. 使用timeout参数
'''
from threading import Thread, Lock
import time
lockA = Lock()
lockB = Lock()
class MyThread(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
if lockA.acquire():
print(self.name + '获取了A锁')
time.sleep(0.1)
if lockB.acquire(timeout=5):
print(self.name + '又获取了B锁,原来还有A锁')
lockB.release()
lockA.release()
class MyThread1(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
if lockB.acquire():
print(self.name + '获取了B锁')
time.sleep(0.1)
if lockA.acquire():
print(self.name + '又获取了A锁,原来还有B锁')
lockA.release()
lockB.release()
if __name__ == '__main__':
t1 = MyThread(MyThread)
t2 = MyThread1(MyThread1)
t1.start()
t2.start()
"""执行结果
<class '__main__.MyThread'>获取了A锁
<class '__main__.MyThread1'>获取了B锁
<class '__main__.MyThread1'>又获取了A锁,原来还有B锁
"""
4 生产者与消费者:两个线程之间的通信
import threading
import queue
import random
import time
def produce(q):
i = 0
while i < 10:
num = random.randint(1, 100)
q.put("生产者产生数据:%d" % num)
print("生产者产生数据:%d" % num)
time.sleep(1)
i += 1
q.put(None)
q.task_done()
def consume(q):
while True:
item = q.get()
if item is None:
break
print("消费者获取到:%s" % item)
time.sleep(4)
q.task_done()
if __name__ == "__main__":
q = queue.Queue(10)
arr = []
th = threading.Thread(target=produce, args=(q,))
th.start()
tc = threading.Thread(target=consume, args=(q,))
tc.start()
th.join()
tc.join()
print("END")