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

下面是详细讲解“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之从格式化表达式到方法

    以下是“跟老齐学Python之从格式化表达式到方法”的完整攻略: 格式化表达式 Python中的格式化表达式是一种用于格式化字符串的语法。它使用百分号(%)作为占位符,并将占位符替换为实际的值。 以下是一个示例代码,用于演示如何使用格式化表达式: name = ‘Alice’ age = 25 print(‘My name is %s and I am %d…

    python 2023年5月14日
    00
  • Java中 % 与Math.floorMod() 区别详解

    首先来看一下 % 和 Math.floorMod() 的区别。 % 运算符 在Java中,% 运算符用于计算两个数值之间的模运算,即计算除法操作的余数。 举个例子: int a = 7; int b = 3; int result1 = a % b; // result1 = 1 在这个例子中,a % b 计算的结果是 1,代表 a 除以 b 的余数是 1。…

    python 2023年6月3日
    00
  • Python使用 TCP协议实现智能聊天机器人功能

    下面是使用Python实现智能聊天机器人的攻略。 1. 确定使用的Python库 使用Python实现TCP协议的网络编程,需要使用Python标准库中的socket模块。同时,也可以使用第三方库如twisted、gevent等来简化操作。 2. 实现网络连接 实现网络连接需要调用socket模块中的方法,使用socket.socket()方法创建socke…

    python 2023年5月23日
    00
  • Python计算开方、立方、圆周率,精确到小数点后任意位的方法

    Python计算开方、立方、圆周率,精确到小数点后任意位的方法 在Python中,计算开方、立方、圆周率以及精确到小数点后任意位的方法多种,下面将分别进行介绍。 1. 计算开方 Python中计算开方可以使用math库中的sqrt函数,也使用幂运算符(**)。 使用math库 import math x = 16 y = math.sqrt(x) print…

    python 2023年5月14日
    00
  • 3分钟学会一个Python小技巧

    下面我将详细讲解“3分钟学会一个Python小技巧”的完整攻略,攻略如下: 1. 确认目标 首先,我们需要明确自己的学习目标。Python是一门广泛应用于各行各业的语言,如何选择适合自己的技巧,需要先明确自己的应用场景。 例如,如果我们需要在Python中处理大型数据集,那么我们可以学习使用numpy库进行高效的数据处理。 2. 寻找资料 在确定自己的学习目…

    python 2023年6月2日
    00
  • python实现文件路径和url相互转换的方法

    要实现python中文件路径和url之间的相互转换,我们可以借助于Python内置的os和urllib.parse模块。 将文件路径转为url 先介绍如何将文件路径转为url。我们可以通过以下代码示例来实现: import os import urllib.parse # 文件路径 file_path = ‘/Users/xxx/Projects/test.…

    python 2023年6月3日
    00
  • Python 字符串使用多个分隔符分割成列表的2种方法

    使用多个分隔符将字符串分割成列表通常是在数据处理和解析文本时非常有用的一种技巧。Python 提供了多种方法实现该功能,本文将介绍两种常用的方法。 方法一:使用 re 模块 Python re 模块提供了丰富的正则表达式支持,可以用来处理字符串的复杂匹配和替换。使用 re.split() 方法可以方便地将字符串按照多个不同的分隔符分割成列表。 import …

    python 2023年5月14日
    00
  • python 集合 并集、交集 Series list set 转换的实例

    在Python中,可以使用集合(set)来进行集合运算,包括并集、交集等。同时,我们也可以将Series、List等数据类型转换为集合进行运算。下将介绍两个示例,分别演示了集的并集、交集运算以及Series、List转换为集合的方法。 示例一:集合的并集、交集运算 # 集合的并集、交集运算 set1 = {1, 2, 3, 4, 5} set2 = {4, …

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