python多线程锁在进行号码更改时无法正常工作

问题描述 投票:1回答:1

我现在正在学习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(),有谁可以帮助解释这种奇怪之处。

python-3.x visual-studio-code python-multithreading
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.