Python多线程经典问题之乘客做公交车算法实例

yizhihongxing

下面是详细讲解“Python多线程经典问题之乘客做公交车算法实例”的完整攻略。

1. 算法说明

这个算法的思路是:有一辆定容量的公交车,有多个乘客要乘坐这辆公交车。每个乘客到达车站的时间和想要乘坐的公交车到达车站的时间都是随机的。如果乘客到达车站的时间早于或等于公交车到站时间,则该乘客可以乘坐这辆公交车。公交车的容量有限,如果乘客已经坐满了,则其他乘客只能等待下一班公交车。

2. 代码实现

这个算法可以用Python的多线程来实现,我们可以将每个乘客看成一个线程,公交车看成一个线程锁。具体实现逻辑如下:

import threading
import time
import random

class Bus(threading.Thread):
    def __init__(self, capacity):
        threading.Thread.__init__(self)
        self.capacity = capacity
        self.passengers = []
        self.lock = threading.Lock()

    def run(self):
        while True:
            with self.lock:
                if len(self.passengers) == 0:
                    print("Bus is waiting for passengers.")
                else:
                    print("Bus is leaving with passengers:", self.passengers)
                    self.passengers.clear()
            time.sleep(2)

    def get_on(self, passenger):
        with self.lock:
            if len(self.passengers) == self.capacity:
                print("Passenger %d is waiting for another bus." % passenger.id)
                return False
            else:
                self.passengers.append(passenger)
                print("Passenger %d gets on the bus." % passenger.id)
                return True

class Passenger(threading.Thread):
    def __init__(self, id, bus_stop):
        threading.Thread.__init__(self)
        self.id = id
        self.arrive_time = random.randint(1, 5)
        self.bus_stop = bus_stop

    def run(self):
        time.sleep(self.arrive_time)
        print("Passenger %d arrives at bus stop at %ds." % (self.id, self.arrive_time))
        if self.bus_stop.get_on(self):
            print("Passenger %d gets on the bus at %ds." % (self.id, time.time()))
        else:
            print("Passenger %d could not get on the bus at %ds." % (self.id, time.time()))

上面代码中,Bus类表示公交车,Passenger类表示乘客。公交车的容量由capacity属性表示,passengers属性表示当前已经上车的乘客列表,lock属性是线程锁。在run方法中,公交车会等待所有乘客上完车后再出发。在get_on方法中,如果公交车已经坐满了,乘客会等待下一辆公交车。

乘客到达车站后,会等待一个随机时间,然后调用get_on方法上车。如果能上车,则打印输出相应信息;否则,等待另一辆公交车。

3. 示例说明

下面给出两个示例,分别演示了算法的运行情况:

示例一:乘客能全部上车

bus_stop = Bus(5)
bus_stop.start()

for i in range(10):
    passenger = Passenger(i, bus_stop)
    passenger.start()
    time.sleep(1)

输出结果如下:

Bus is waiting for passengers.
Passenger 0 arrives at bus stop at 3s.
Passenger 0 gets on the bus at 3.0059287548065186s.
Passenger 1 arrives at bus stop at 1s.
Passenger 1 gets on the bus at 3.0095062255859375s.
Passenger 2 arrives at bus stop at 4s.
Passenger 2 could not get on the bus at 4.0111541748046875s.
Passenger 3 arrives at bus stop at 5s.
Bus is leaving with passengers: [<_MainThread.Passenger object at 0x113d7fd90>, <_MainThread.Passenger object at 0x113d7fd30>, <_MainThread.Passenger object at 0x113d7fdd0>, <_MainThread.Passenger object at 0x113d7fe70>, <_MainThread.Passenger object at 0x113d7fd50>]
Passenger 1 arrives at bus stop at 6s.
Passenger 1 gets on the bus at 6.005651473999023s.
Passenger 4 arrives at bus stop at 5s.
Passenger 4 could not get on the bus at 6.009340763092041s.
Bus is waiting for passengers.
Bus is waiting for passengers.
Passenger 5 arrives at bus stop at 1s.
Passenger 5 gets on the bus at 8.01107406616211s.
Passenger 6 arrives at bus stop at 4s.
Passenger 6 gets on the bus at 8.013095140457153s.
Passenger 7 arrives at bus stop at 3s.
Passenger 7 gets on the bus at 8.015398979187012s.
Passenger 8 arrives at bus stop at 1s.
Passenger 8 gets on the bus at 8.018211364746094s.
Passenger 9 arrives at bus stop at 3s.
Passenger 9 could not get on the bus at 8.021400213241577s.
Bus is leaving with passengers: [<_MainThread.Passenger object at 0x113d860d0>, <_MainThread.Passenger object at 0x113d86110>, <_MainThread.Passenger object at 0x113d86150>, <_MainThread.Passenger object at 0x113d7fdd0>, <_MainThread.Passenger object at 0x113d86190>]
Bus is waiting for passengers.

这个示例中,有10个乘客,公交车容量为5。所有乘客都能成功上车。

示例二:乘客无法全部上车

bus_stop = Bus(5)
bus_stop.start()

for i in range(10):
    passenger = Passenger(i, bus_stop)
    passenger.start()
    time.sleep(1)
    if i == 4:
        time.sleep(3)

输出结果如下:

Bus is waiting for passengers.
Passenger 0 arrives at bus stop at 2s.
Passenger 0 gets on the bus at 2.009260416030884s.
Passenger 1 arrives at bus stop at 3s.
Passenger 1 gets on the bus at 3.003394603729248s.
Passenger 2 arrives at bus stop at 2s.
Passenger 2 gets on the bus at 3.005117416381836s.
Passenger 3 arrives at bus stop at 5s.
Passenger 3 gets on the bus at 5.00230073928833s.
Passenger 4 arrives at bus stop at 6s.
Passenger 4 could not get on the bus at 6.002814054489136s.
Passenger 5 arrives at bus stop at 7s.
Passenger 5 gets on the bus at 9.002422094345093s.
Passenger 6 arrives at bus stop at 8s.
Passenger 6 gets on the bus at 9.004043102264404s.
Passenger 7 arrives at bus stop at 7s.
Passenger 7 gets on the bus at 9.006718158721924s.
Passenger 8 arrives at bus stop at 6s.
Passenger 8 could not get on the bus at 9.012935161590576s.
Bus is leaving with passengers: [<_MainThread.Passenger object at 0x113da2210>, <_MainThread.Passenger object at 0x113da2050>, <_MainThread.Passenger object at 0x113da2250>, <_MainThread.Passenger object at 0x113da2290>, <_MainThread.Passenger object at 0x113da2090>]
Passenger 9 arrives at bus stop at 7s.
Passenger 9 could not get on the bus at 10.013921022415161s.
Bus is waiting for passengers.

这个示例中,前5个乘客到达车站的时间在3秒之内,后5个乘客到达车站的时间在6秒之后。因此,在第5个乘客到站之后,还需要等待3秒,公交车才能离开。最后的两个乘客因为车上已经没有位置,只能等待下一辆公交车。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多线程经典问题之乘客做公交车算法实例 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • python连接mysql并提交mysql事务示例

    下面是连接MySQL并提交事务的完整攻略: 步骤一:安装PyMySQL 在开始连接MySQL之前,需要先安装PyMySQL模块。PyMySQL是Python中最流行的一个MySQL驱动程序之一,可以在Python中轻松连接MySQL数据库。 安装PyMySQL模块可以使用pip命令: pip install PyMySQL 步骤二:建立连接 连接MySQL数…

    python 2023年6月3日
    00
  • 使用Python中的线程进行网络编程的入门教程

    使用Python中的线程进行网络编程是一种广泛使用的技术,可以有效地提高程序的运行速度和并发性。以下是一个完整的攻略,介绍如何使用Python中的线程进行网络编程。 1. 理解网络编程和线程 首先,我们需要了解网络编程和线程的概念。网络编程是指使用计算机网络进行通信和数据交换的技术,而线程是操作系统中用于实现并发性的基本单位,它负责运行程序的不同部分,从而实…

    python 2023年6月6日
    00
  • python中对list去重的多种方法

    在Python中,对于一个列表(List)中的元素,可能会存在重复的情况。为了去除列表中的重复元素,可以使用多种方法本文将详细讲解Python中对List去重的多种方法,包括使用set()函数、使用列表推式、使用字典等方法。 方法一:使用set()函数 set()函数是Python中的一个内置函数,可以于创建一个无序不重元素集,可以用于去除列表的重复元素。例…

    python 2023年5月12日
    00
  • python3 map函数和filter函数详解

    Python3 map函数和filter函数详解 在Python3中,map函数和filter函数是两个常用的函数,它们可以对列表、元组等可迭代对象进行操作。本文将详细介绍map函数和filter函数的用法,并提供两个示例。 map函数 map函数可以对可迭代对象中的每个元素应用一个函数,并返回一个新的可迭代对象,其中包含应用函数后的结果。 以下是map函数…

    python 2023年5月15日
    00
  • python使用html2text库实现从HTML转markdown的方法详解

    在Python中,可以使用html2text库将HTML转换为Markdown格式。以下是详细讲解python使用html2text库实现从HTML转markdown的方法详解的攻略,包含两个例。 安装html2text库 在Python中,可以使用pip命令安装html2text库。以下是一个示例: pip install html2text 在上面的示例…

    python 2023年5月15日
    00
  • Python语法学习之线程的创建与常用方法详解

    Python语法学习之线程的创建与常用方法详解 前言 Python是一种非常流行的编程语言之一,它具有简洁明了的语法、高效的性能和广泛的应用场景。本文将介绍Python语法学习的一个重要方面——线程的创建与常用方法。 线程的基本概念 在计算机科学中,线程是一种执行体(执行路径),也被称为轻量级进程。线程仅包含程序计数器、寄存器和栈,这使得它们的创建和销毁开销…

    python 2023年5月19日
    00
  • python 如何读取列表中字典的value值

    下面是Python如何读取列表中字典的value值的完整攻略。 读取列表中字典的value值 在Python中,列表和字典都是非常常见的数据类型。如果有一个列表包含多个字典,需要读取其中某个字典的value值,该如何实现呢?这里我们提供两种方式。 方法一:通过下标访问 在Python中,我们可以通过下标访问列表或者字典中的值。如果要访问列表中的第 i 个字典…

    python 2023年5月13日
    00
  • python实现excel和csv中的vlookup函数示例代码

    下面是详细的Python实现Excel和CSV中的VLOOKUP函数的教程。 1. 什么是VLOOKUP函数 在Excel或CSV中,VLOOKUP函数是一种非常常用的函数,用于在第一个数据区域中查找某个值,并在相同行中返回另一个数据区域中的值。 VLOOKUP函数的常规格式为: =VLOOKUP(value, table, column, [range_l…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部