27 线程

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)  # 理论值是money:8000000,实际值是money:87346403
--------------------------------------------------------------------------------------
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)  # money: 80000000

3 死锁

# 死锁
'''
开发过程中使用线程,在线程间共享多个资源的时候,
如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
尽管死锁很少发生,但一旦发生就会造成应用的停止响应,程序不做任何事情。

避免死锁:
解决:
1. 重构代码
2. 使用timeout参数
'''
from threading import Thread, Lock
import time

lockA = Lock()
lockB = Lock()

class MyThread(Thread):  # 重写thread方法
    def __init__(self, name):
        super().__init__()
        self.name = name
    def run(self):  # start()启动
        if lockA.acquire():  # 如果可以获取到锁则返回True
            print(self.name + '获取了A锁')
            time.sleep(0.1)
            if lockB.acquire(timeout=5):  # 不写timeout就进行阻塞变成死锁
                print(self.name + '又获取了B锁,原来还有A锁')
                lockB.release()
            lockA.release()

class MyThread1(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name
    def run(self):  # start()
        if lockB.acquire():  # 如果可以获取到锁则返回True
            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")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值