[英]Python stuck in a single thread of a multi-threaded program
I'm currently writing a program that is attempting to synchronize a visitor, car, pump, and gas station thread at a zoo where guests arrive, wait for an available car, take a tour, then exit, the cars must refuel every 5 rides, and the gas station must refuel every time 3 cars are refilled. 我目前正在编写一个程序,试图同步访客到达的动物园的访客,汽车,泵和加油站线程,等待可用的汽车,游览,然后退出,每5次骑行必须加油,并且每次加油3辆汽车时,加油站必须加油。 My tests are with 35 visitors, 6 cars, 5 gas pumps, and a time interval of 2. The program reads a text file with the number of guests, cars, pumps, and a time interval between visitors boarding vehicles, then uses the data to fill a class.
我的测试是在35位访客,6辆汽车,5个加油站和2个时间间隔下进行的。程序读取文本文件,其中包含访客,汽车,水泵的数量以及访客登车之间的时间间隔,然后使用数据补课。 I create methods for each thread, then create the threads themselves in main.
我为每个线程创建方法,然后在main中自己创建线程。 My problem is that my program gets stuck at 6 vehicles, which is the number specified by the text file, after running my first thread method, visitor_thread, and I cannot tell if any other threads are even running concurrently.
我的问题是,在运行第一个线程方法visitor_thread之后,我的程序被卡在6辆车上,这是文本文件指定的数量,并且我无法确定是否还有其他线程在同时运行。 I am a total novice at multithreading and python alike, and I'm not sure what the problem is.
我是多线程和python领域的新手,但我不确定是什么问题。 I have worked on the project for twelve hours straight and have been stuck at this point for the past four hours.
我已经连续12个小时从事该项目的工作,而在过去的四个小时中,我一直处于这一状态。 In theory, visitor_thread, car_thread, and gas_station_thread should all run concurrently from main, and visitor_thread should have vehicles to work with again after some visitors finish their ride, but I just get stuck with six full cars in an infinite loop within visitor_thread.
从理论上讲,visitor_thread,car_thread和gas_station_thread都应从main并发运行,并且visitor_thread应该在某些访问者完成骑行之后让车辆可以再次使用,但是我只是在visitor_thread内无限循环地陷入了六辆满满的汽车中。 What is causing this infinite loop and how can I make sure all of my threads are actually running?
是什么导致此无限循环,如何确保所有线程都在实际运行?
My code: 我的代码:
from threading import Thread
from threading import Lock
from threading import Event
event = Event()
lock = Lock()
done = Event()
is_done = 0
class Arguments:
def __init__(self, m_visitors, n_cars, k_pumps, t_time, thread_num, _done):
self.m_visitors = m_visitors
self.n_cars = n_cars
self.k_pumps = k_pumps
self.t_time = t_time
self.thread_num = thread_num
self.done = _done
class Car:
def __init__(self, control, rides, time, in_service, int_cus, in_queue):
self.control = control
self.rides = rides
self.time = time
self.in_service = in_service
self.int_cus = int_cus
self.in_queue = in_queue
class Pump:
def __init__(self, control, in_use, car_num, time):
self.control = control
self.in_use = in_use
self.car_num = car_num
self.time = time
class PumpQueue:
def __init__(self, pQueue, MAXsize, front, back, size):
self.q = Lock()
self.pQueue = pQueue
self.MAXsize = MAXsize
self.front = front
self.back = back
self.size = size
def visitor_thread(_visitor):
global is_done
visitor = _visitor
v = visitor.m_visitors
c = visitor.n_cars
p = visitor.k_pumps
t = visitor.t_time
id = visitor.thread_num
i = 0
j = 0
while i < v:
for j in range(0, c):
lock.acquire()
if cars[j].in_service is False and cars[j].rides < 5:
print('\nVisitor %d is currently in car %d' % (i+1, j+1))
cars[j].in_service = True
i += 1
print('\n%d customers waiting for a ride.' % (v - i))
lock.release()
break
lock.release()
lock.acquire()
is_done += 1
lock.release()
def car_thread(_car):
global is_done
carThread = _car
cars_done = 0
v = carThread.m_visitors
c = carThread.n_cars
p = carThread.k_pumps
t = carThread.t_time
id = carThread.thread_num
i = 0
while cars_done == 0:
cars_in_service = 0
while i < c:
lock.acquire()
if cars[i].in_service is True and cars[i].rides < 5:
# Car still being used, add more time
cars[i].time += 1
if cars[i].time == t:
cars[i].in_service = False
cars[i].rides += 1
cars[i].time = 0
if cars[i].rides == 5 and cars[i].in_queue is False:
push(i)
cars[i].in_queue = True
if cars[i].in_service is False:
cars_in_service += 1
i += 1
lock.release()
if cars_in_service == c and is_done >= 1:
cars_done = 1
lock.acquire()
is_done += 1
lock.release()
def gas_station_thread(_gas_station):
global is_done
gas_station = _gas_station
truck = False
cars_filled = 0
v = gas_station.m_visitors
c = gas_station.n_cars
p = gas_station.k_pumps
t = gas_station.t_time
id = gas_station.thread_num
gas_done = 0
pumps_in_service = 0
j = 0
while gas_done == 0:
while j < p:
lock.acquire()
if pumps[j].in_use is True:
pumps[j].time += 1
if pumps[j].time == 3:
lock.acquire()
cars[j].in_service = 0
cars[j].rides = 0
cars[j].time = 0
cars[j].in_queue = False
lock.release()
pumps[j].time = 0
pumps[j].in_use = False
cars_filled += 1
pumps_in_service -= 1
if truck is True and pumps[j].in_use is False:
truck = False
print('Fuel Truck is currently filling up the gas station.')
elif pumps[j].in_use is True and pump_line.size > 0:
pumps_in_service += 1
pumps[j].in_use = True
pumps[j].car_num.pop()
print('Car %d, pump %d' % (pumps[j].car_num + 1, i + 1))
pumps[j].time = 0
j += 1
lock.release()
if cars_filled > 3:
print('The Fuel Truck is on its way')
truck = True
cars_filled = 0
if pumps_in_service == 0 and is_done == 2:
gas_done = True
lock.acquire()
is_done += 1
lock.release()
def pop():
lock.acquire()
fr = pump_line.front
f = pump_line.pQueue[fr]
print("\n%d cars are waiting for pumps" % int(pump_line.size - 1))
if fr < (pump_line.MAXsize - 1):
pump_line.front += 1
else:
pump_line.front = 0
lock.release()
return f
def push(_c):
c =_c
lock.acquire()
b = pump_line.back
pump_line.pQueue[b] = c
print("\n%d cars are waiting for pumps" % int(pump_line.size + 1))
if b < (pump_line.MAXsize - 1):
pump_line.back += 1
else:
pump_line.back = 0
lock.release()
def isEmpty():
lock.acquire()
if (pump_line.front == pump_line.back):
boolean = True
else:
boolean = False
lock.release()
return boolean
if __name__ == "__main__":
arguments = Arguments(0, 0, 0, 0, 0, False)
main = Arguments(0, 0, 0, 0, 0, False)
thread = []
round_number = 0
io_control = 0
input_file = []
number_of_threads = 3
print("Enter the name of the text file to use as input:")
while io_control == 0:
try:
filename = input()
input_file = open(filename)
io_control = 1
except IOError:
print("Specified file does not exist, enter a different text file:")
# parse file into lines, separating by endlines
file_lines = []
num_lines = 0
for line in input_file:
line = line.replace(",", " ")
line = line.split()
num_lines += 1
if line:
line = [int(i) for i in line]
file_lines.append(line)
while main.done is False and round_number < num_lines:
main.m_visitors = int(file_lines[round_number][0])
main.n_cars = int(file_lines[round_number][1])
main.k_pumps = int(file_lines[round_number][2])
main.t_time = int(file_lines[round_number][3])
print("\nRound Number: %d" % (round_number + 1))
if main.n_cars == 0:
print('No data to read in this round, press enter to continue:')
input()
print("Number of Visitors: %d" % main.m_visitors)
print("Number of Cars: %d" % main.n_cars)
print("Number of Pumps: %d" % main.k_pumps)
print("Units of Time: %d" % main.t_time)
M = main.m_visitors
N = main.n_cars
K = main.k_pumps
T = main.t_time
thread_info = []
cars = []
pumps = []
for i in range(0, 3):
temp = Arguments(M, N, K, T, i, False)
thread_info.append(temp)
for i in range(0, N):
temp = Car(0, 0, 0, False, 0, False)
cars.append(temp)
for i in range(0, K):
temp = Pump(0, False, 0, 0)
pumps.append(temp)
pump_line = PumpQueue(0, 0, 0, 0, N)
visitorThread = Thread(target=visitor_thread, args=(thread_info[0],))
thread.append(visitorThread)
carsThread = Thread(target=car_thread, args=(thread_info[1],))
thread.append(carsThread)
gasThread = Thread(target=gas_station_thread, args=(thread_info[2],))
thread.append(gasThread)
visitorThread.start()
carsThread.start()
gasThread.start()
visitorThread.join()
carsThread.join()
gasThread.join()
round_number += 1
My output: 我的输出:
Round Number: 1 Number of Visitors: 35 Number of Cars: 6 Number of Pumps: 5 Units of Time: 2
轮数:1访客人数:35轿车数量:6泵数量:5时间单位:2
Visitor 1 is currently in car 1
访客1目前在汽车1中
34 customers waiting for a ride.
34位顾客在等车。
Visitor 2 is currently in car 2
访客2目前在车2中
33 customers waiting for a ride.
33位顾客在等车。
Visitor 3 is currently in car 3
访客3当前在汽车3中
32 customers waiting for a ride.
32位顾客在等车。
Visitor 4 is currently in car 4
访客4当前在汽车4中
31 customers waiting for a ride.
31位顾客在等车。
Visitor 5 is currently in car 5
访客5当前在车5中
30 customers waiting for a ride.
30位顾客在等车。
Visitor 6 is currently in car 6
访客6目前在汽车6中
29 customers waiting for a ride.
29位顾客在等车。
I think there's an index problem here: 我认为这里存在索引问题:
if cars[j].in_service is False and cars[i].rides < 5:
should be 应该
if cars[j].in_service is False and cars[j].rides < 5:
Index for cars is j not i 汽车指数不是j
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.