如題,我有三個執行緒,每個執行緒都有task1,wait_task,task2,task3四個步驟。除了這三個并行的執行緒之外,另外還有一個計時執行緒。
我希望前三個執行緒,在全部完成task1之后,計時加1,然后全部完成wait_task之后,計時再加1,然后全部依次完成task3,計時再加1,然后全部完成task4,計時再加1.
代碼在下面,然而運行結果不是我想象的這樣。哪位大佬能指出問題在哪,并幫忙給予糾正?
from threading import Thread
import threading
cond = threading.Condition()
def main():
global total_current_time, total_last_time
total_current_time = 0
total_last_time = 0
global robot_tasks_dict
global flag
robot_tasks_dict = dict()
# robot_steps_finished = False
robot_task_list = []
count_time_thread = Thread(target=count_time, args=())
for i in range(3):
robot_task_thread = Thread(target=robot_task, args=(i,))
robot_task_list.append(robot_task_thread)
count_time_thread.start()
for thread in robot_task_list:
thread.start()
def count_time():
print(type(cond))
cond.acquire()
global flag
flag = False
values = robot_tasks_dict.values()
global total_last_time
global total_current_time
result = 1
for i in values:
result = result * i
print('result = %d' % result)
if result == 1:
total_last_time = total_current_time
total_current_time += 1
print('-----total_current_time = %d' % total_current_time)
flag = True
cond.notify_all()
cond.wait()
cond.release()
def robot_task(robotid):
task1(robotid)
wait_task(robotid)
task2(robotid)
task3(robotid)
def task1(robotid):
cond.acquire()
global flag
if flag == False:
cond.wait()
global robot_tasks_dict
robot_tasks_dict[threading.current_thread().name] = 0
print('----------robot[%s] task1---------------' % robotid)
robot_tasks_dict[threading.current_thread().name] = 1
cond.notify_all()
cond.wait()
cond.release()
def task2(robotid):
cond.acquire()
global flag
if flag == False:
cond.wait()
global robot_tasks_dict
robot_tasks_dict[threading.current_thread().name] = 0
print('----------robot[%s] task2---------------' % robotid)
robot_tasks_dict[threading.current_thread().name] = 1
cond.notify_all()
cond.wait()
cond.release()
def task3(robotid):
cond.acquire()
global flag
if flag == False:
cond.wait()
global robot_tasks_dict
robot_tasks_dict[threading.current_thread().name] = 0
print('----------robot[%s] task3---------------' % robotid)
robot_tasks_dict[threading.current_thread().name] = 1
cond.notify_all()
cond.wait()
cond.release()
def wait_task(robotid):
cond.acquire()
global flag
if flag == False:
cond.wait()
global robot_tasks_dict
robot_tasks_dict[threading.current_thread().name] = 0
print('----------robot[%s] wait task---------------' % robotid)
robot_tasks_dict[threading.current_thread().name] = 1
cond.notify_all()
cond.wait()
cond.release()
if __name__ == '__main__':
main()
uj5u.com熱心網友回復:
用狀態控制吧
from threading import Thread
import threading
import time
def main():
global task1_pass,wait_pass,task2_pass,task3_pass
task1_pass = False
wait_pass = False
task2_pass = False
task3_pass = False
global total_current_time, total_last_time
total_current_time = 0
total_last_time = 0
global robot_tasks_dict
global flag
robot_tasks_dict = {0:0,1:0,2:0}
robot_task_list = []
count_time_thread = Thread(target=count_time, args=())
for i in range(3):
robot_task_thread = Thread(target=robot_task, args=(i,))
robot_task_list.append(robot_task_thread)
count_time_thread.start()
for thread in robot_task_list:
thread.start()
def count_time():
global total_last_time
global total_current_time
global task1_pass, wait_pass, task2_pass, task3_pass
while not task3_pass:
values = robot_tasks_dict.values()
result = 1
for i in values:
result = result * i
# print('result = %d' % result)
if result == 1:
total_last_time = total_current_time
total_current_time += 1
print('-----total_current_time = %d' % total_current_time)
for k in robot_tasks_dict.keys():
robot_tasks_dict[k] = 0
if task2_pass: task3_pass = True
elif wait_pass: task2_pass = True
elif task1_pass: wait_pass = True
else: task1_pass = True
def robot_task(robotid):
task1(robotid)
wait_task(robotid)
task2(robotid)
task3(robotid)
def task1(robotid):
global task1_pass
global robot_tasks_dict
robot_tasks_dict[robotid] = 0
print('----------robot[%s] task1---------------' % robotid)
robot_tasks_dict[robotid] = 1
while not task1_pass:
time.sleep(0.001)
def task2(robotid):
global task2_pass
global robot_tasks_dict
robot_tasks_dict[robotid] = 0
print('----------robot[%s] task2---------------' % robotid)
robot_tasks_dict[robotid] = 1
while not task2_pass:
time.sleep(0.001)
def task3(robotid):
global task3_pass
global robot_tasks_dict
robot_tasks_dict[robotid] = 0
print('----------robot[%s] task3---------------' % robotid)
robot_tasks_dict[robotid] = 1
while not task3_pass:
time.sleep(0.001)
def wait_task(robotid):
global wait_pass
global robot_tasks_dict
robot_tasks_dict[robotid] = 0
print('----------robot[%s] wait task---------------' % robotid)
robot_tasks_dict[robotid] = 1
while not wait_pass:
time.sleep(0.001)
if __name__ == '__main__':
main()
uj5u.com熱心網友回復:
多謝回復!有個疑問,如果我每個執行緒只有四步的話還好說,用四個變數就可以了,假設每個執行緒有上百、上千個步驟,并且有的步驟里有for回圈、并且每次要讓所有執行緒只去回圈for回圈的一次,那這么搞就不行了吧?
uj5u.com熱心網友回復:
和任務數關系不大,同樣可以放陣列或字典里,我task2里放一個for回圈
from threading import Thread
import time
def main():
thread_num = 3
global task_no, robot_tasks_no, robot_finish_flag
task_no = 1
robot_tasks_no = dict(zip(range(thread_num),[1]*thread_num)) # {0:1, 1:1, 2:1}
robot_finish_flag = dict(zip(range(thread_num),[0]*thread_num)) # {0:0, 1:0, 2:0}
global total_current_time, total_last_time
total_current_time = 0
total_last_time = 0
robot_task_list = []
count_time_thread = Thread(target=count_time, args=())
for i in range(thread_num):
robot_task_thread = Thread(target=robot_task, args=(i,))
robot_task_list.append(robot_task_thread)
count_time_thread.start()
for thread in robot_task_list:
thread.start()
def wait_next_step(robotid):
global task_no, robot_tasks_no
robot_tasks_no[robotid] += 1
while robot_tasks_no[robotid] > task_no:
time.sleep(0.001)
def count_time():
global task_no, robot_tasks_no, robot_finish_flag
global total_last_time
global total_current_time
while True:
values = robot_tasks_no.values()
result = 1
for i in values:
result = result * (i-task_no)
# print('result = %d' % result)
if result == 1:
total_last_time = total_current_time
total_current_time += 1
print('-----total_current_time = %d' % total_current_time)
task_no += 1
all_finish = 1
for i in robot_finish_flag.values():
all_finish = all_finish * i
if all_finish:
print('--------------all finish----------------')
break
def robot_task(robotid):
task1(robotid)
wait_task(robotid)
task2(robotid)
task3(robotid)
def task1(robotid):
print('----------robot[%s] task1---------------' % robotid)
wait_next_step(robotid)
def task2(robotid):
for n in range(10):
print('----------robot[%s] task2----loop %s-----------' % (robotid, n))
wait_next_step(robotid)
def task3(robotid):
global robot_tasks_no,robot_finish_flag
print('----------robot[%s] task3-----------'% robotid)
robot_tasks_no[robotid] += 1
robot_finish_flag[robotid] = 1
def wait_task(robotid):
print('----------robot[%s] wait task---------------' % robotid)
wait_next_step(robotid)
if __name__ == '__main__':
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/75147.html
