第13章 2 进程和线程

发布时间:2024年01月17日

多个线程共享数据带来的问题及lock锁的使用 p186

多个线程在同一个进程中运行,多个线程共享这个进程中的全局变量

import threading,time

ticket=50 # 代表50张车票

def sale_ticket():
    global ticket
    # 每个排队窗口100人
    for i in range(100):
        if ticket>0:
            print(f'{threading.current_thread().name}正在出售第{ticket}张票')
            ticket-=1
        time.sleep(1)

if __name__ == '__main__':
    for i in range(3):
        t=threading.Thread(target=sale_ticket)
        t.start()
'''
Thread-3正在出售第11张票Thread-1正在出售第11张票Thread-2正在出售第11张票

多线程操作数据带来不安全的问题,可能会多个线程同时访问公共资源/临界区,造成数据错误
'''

采用Lock锁对象去解决这类问题。


上锁:acquire()方法
解锁:release()方法

代码实例:

import threading,time

ticket=50 # 代表50张车票

# 创建锁对象
lock_obj=threading.Lock()

def sale_ticket():
    global ticket
    # 每个排队窗口100人
    for i in range(100):
        lock_obj.acquire() # 上锁
        if ticket>0:
            print(f'{threading.current_thread().name}正在出售第{ticket}张票')
            ticket-=1
        lock_obj.release() # 解锁
        time.sleep(1)

if __name__ == '__main__':
    for i in range(3):
        t=threading.Thread(target=sale_ticket)
        t.start()

生产者与消费者问题 p187

是线程模型中的经典问题,与编程语言无关。

当程序中出现了明确的两类任务,一个任务负责生产数据,另一个任务负责处理生产的数据时,就可以使用该模式

Python内置模块queue中的Queue类

方法名称功能描述
put(item)向队列中放置数据,若队列为满,则阻塞
get()从队列中取走数据,若队列为空,则阻塞
join()若队列不为空,则等待队列为空
task_done()消费者从队列中取走一项数据,当队列变为空时,唤醒调用join()的线程

代码实例:

import threading,queue,time

# 创建一个生产者类
class Producer(threading.Thread):
    def __init__(self,name,queue):
        threading.Thread.__init__(self,name=name)  # 使用super()会报错,原因不知道
        self.queue=queue

    def run(self):
        for i in range(1,6):
            print(f'生产者线程{self.name}将产品{i}放入队列')
            self.queue.put(i)
            time.sleep(1)

        print('生产者完成了所有数据的存放')

# 创建一个消费者类
class Consumer(threading.Thread):
    def __init__(self,name,queue):
        threading.Thread.__init__(self,name=name)  # 使用super()会报错,原因不知道
        self.queue=queue


    def run(self):
        for _ in range(5):
            value=self.queue.get()
            print(f'消费者线程{self.name}取出了产品{value}')
            time.sleep(1)

        print('消费者完成了所有数据的取出')

if __name__ == '__main__':
    print('主线程开始执行')
    # 创建队列
    q=queue.Queue()
    # 创建生产者线程
    p=Producer('Producer',q)
    # 创建消费者线程
    c=Consumer('Consumer',q)

    p.start()
    c.start()

    p.join()
    c.join()
    print('主线程执行结束')
文章来源:https://blog.csdn.net/engineer0/article/details/135642363
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。