IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> Python 多线程卖票问题 -> 正文阅读

[开发工具]Python 多线程卖票问题

Python 多线程卖票问题

在学习多线程的时候,我们经常要学习到多窗口售票这一经典案例,今天我们将用Python语言写一个简单易懂的售票程序,帮助大家学习理解
有以下要求:
第一、不能出现打印出现混乱
第二、比单线程快
第三、票数不能为负数
先上网上百度到的代码

import threading

list_ticket = []
lock = threading.Lock()  # 获取线程锁
num = 100
j = 0

for i in range(1, num + 1):
    ticket_num = '0' * (3 - len(str(i))) + str(i)
    list_ticket.append(ticket_num)


def seel_ticket(k):
    global list_ticket
    global j
    while 1:
        lock.acquire()
        print(k, '号正在打印票')
        if j != 100:
            thre = list_ticket[j]
            j += 1
            print(k, "号出票成功,票号为:", thre)
        else:
            print('票已经卖完')
            break
        lock.release()


list_thread = []
for i in range(10):
    thread = threading.Thread(target=seel_ticket, args=(i + 1,))
    list_thread.append(thread)
for i in list_thread:
    i.start()

在这里插入图片描述
我们分析以下他的代码都是一个线程在卖票,极其不符合要求。
我上我写的源代码

# -*-coding:  UTF-8
# @Time    :  2021/10/17 14:55
# @Author  :  Cooper
# @FileName:  互斥锁.py
# @Software:  PyCharm
from threading import Thread, Lock
import threading
import time

n = 100
mutex = Lock()


def task():
    global n
    while n > 0:
        mutex.acquire()  # 上锁
        if n > 0:
            n -= 1
            time.sleep(0.1)
            print('购买成功,剩余%d 张电影票' % n, '当前的线程是:', threading.current_thread().name)
        else:
            print('票已经卖完了')
            break
        mutex.release()


if __name__ == '__main__':
    print('主线程开始')
    t_l = []
    for i in range(10):
        t = Thread(target=task)
        t_l.append(t)
        t.start()
    for t in t_l:
        t.join()
    print('主线程结束')

运行结果如下:

在这里插入图片描述
但是不满意的这个程序不会自己停止,如果有大神懂的请多多指教。
当我们把互斥锁注释掉时候,输出程序出现混乱
在这里插入图片描述
当上锁的位置不对时候

def task():
    global n
    mutex.acquire()  # 上锁
    while n > 0:
        if n > 0:
            n -= 1
            time.sleep(0.1)
            print('购买成功,剩余%d 张电影票' % n, '当前的线程是:', threading.current_thread().name)
        else:
            print('票已经卖完了')
            break
    mutex.release()


可以看见只有一个线程在买票
在这里插入图片描述
我以为是我们的程序有问题,后面看了网上其他人的代码,我发现是互斥锁的问题。看如下的代码:

import threading
from time import sleep, ctime

N = 100  # 100张票


def Sell(name):
    global N

    while True:
        if N > 0:
            sleep(0.1)  # 加入此句,可以让线程卖出第0张票或同一张票
            print("{}卖出第{}张票!\n".format(name, N))
            N = N - 1


def main():
    threads = {}

    for i in ("A", "B"):
        # 实例化每个 Thread 对象,把函数和参数传递进去,返回 Thread 实例
        t = threading.Thread(target=Sell, args=(i,))
        threads[i] = t  # 分配线程

    for i in ("A", "B"):
        threads[i].start()  # 开始执行多线程

    for i in ("A", "B"):
        threads[i].join()  # 等待线程结束或超时,然后再往下执行

    print("程序结束!")


if __name__ == '__main__':
    main()

运行结果如下:
在这里插入图片描述
程序还是不会停止,就是互斥锁的问题,当我们把互斥锁注释掉之后,程序可以停止,不是逻辑问题,是互斥锁的问题。如果大佬知道如何解决,请告知。

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:35:25  更:2021-10-18 17:37:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:53:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码