我现在正在学习python3多线程,并尝试测试以下代码。代码的作用是使用多线程在名为balance
的函数中修改全局数字test_change
(初始值= 0),方法是先加然后减去相同的数字,然后使用线程锁确保balance
]变量将一次只能被一个线程更改。我将其循环100000次或更多次,以检查天气是否显示预期值0,但是,非常令人失望的是,0并不总是我能得到的答案。这是下面的代码。我正在使用的编辑器是Vscode。
balance = 0
def test_change(n):
global balance
balance += n
balance -= n
# print("in {}, balance is {}".format(threading.current_thread().name, balance))
class MyThread(threading.Thread):
""" self-defined threading class """
def __init__(self, target_fun, fun_args, loop=False):
threading.Thread.__init__(self)
self.target_fun = target_fun
self.fun_args = fun_args
self.loop = loop
self.threadLock = threading.Lock()
def run(self): # overwrite parent run function
if not self.loop:
self.target_fun(*self.fun_args)
elif self.loop:
# with self.threadLock: # balance [15]
# for i in range(1000000):
# self.target_fun(self.fun_args)
for i in range(100000):
self.threadLock.acquire()
self.target_fun(self.fun_args)
self.threadLock.release()
nums = [5, 12]
thread_list = []
for i in range(2): # create 2 thread object
t = MyThread(target_fun=test_change, fun_args=nums[i], loop=True)
thread_list.append(t)
for i in range(len(thread_list)): # start thread object
thread_list[i].start()
for i in range(len(thread_list)): # stop main thread till subthread finishes
thread_list[i].join()
print("balance [{}]".format(balance)) # expected to be 0 always
print("subthread finishes")
这是显示的执行结果的一部分,您可以看到最后的输出。
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 &ython.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugface_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 &ython.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugface_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 2863 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 2870 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3383 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3389 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3394 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3401 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3406 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [0]
subthread finishes
(face36) D:\P_project_SRS\face_cumstom_dual_cam_0506> cd d:\P_project_SRS\face_cumstom_dual_cam_0506 && cmd /C "C:\LeeSRSPrgoramFile\A_anaconda\envs\face36\python.exe c:\Users\lijin\.vscode\extensions\ms-python.python-2020.5.80290\pythonFiles\lib\python\debugpy\no_wheels\debugpy\launcher 3414 -- d:\P_project_SRS\face_cumstom_dual_cam_0506\threading_producer_consumer.py "
balance [12] --> this is the result should never happened when using a lock.
subthread finishes
我已经尝试过两个用于启用锁的python语法,它们分别为with self.threadLock:
(请参阅类运行函数中注释掉的部分)和self.threadLock.acquire(), self.threadLock.release()
,有谁可以帮助解释这种奇怪之处。