python 多线程锁在更改号码时未按预期工作
python multi-threading lock is not working as expected when doing number change
我正在学习 python3 多线程并尝试测试以下代码。代码所做的是使用多线程修改名为 test_change
的函数中的全局数字 balance
(初始值 = 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:
(请参阅 class 运行 函数中注释掉的部分)和 self.threadLock.acquire(), self.threadLock.release()
, 有没有人可以帮忙解释一下这个怪事。
您创建的每个线程都被赋予其 自己的 个 Lock()
实例,并且它们彼此无关。为了提供互斥,两个线程都必须使用 same Lock
对象。例如,在模块级别创建 Lock
的单个实例,并将其传递给线程的构造函数。
根据@Tim Peters 的建议,我将代码修改如下。
import time
import threading
from threading import Thread
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, lock, target_fun, fun_args, loop=False): # added a shared lock parameter
threading.Thread.__init__(self)
self.target_fun = target_fun
self.fun_args = fun_args
self.loop = loop
self.lock = lock # this is the shared lock
def run(self): # overwrite parent run function
if not self.loop:
self.target_fun(*self.fun_args)
elif self.loop:
for i in range(100):
with self.lock: # "with" after "for" so that both thread change the "balance" variable alternatively
self.target_fun(self.fun_args)
nums = [5, 12]
thread_list = []
thread_muduleLock = threading.Lock() # added a shared lock
start = time.perf_counter()
for i in range(2):
t = MyThread(thread_muduleLock, target_fun=test_change, fun_args=nums[i], loop=True) # passing the shared lock to the thread constructor
thread_list.append(t)
for i in range(len(thread_list)):
thread_list[i].start()
for i in range(len(thread_list)):
thread_list[i].join()
end = time.perf_counter()
total = end - start
print("balance [{}], total time [{}]".format(balance, total))
print("subthread finishes")
执行结果如下:
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
balance [0], total time [0.1192338]
subthread finishes
除了上面那些,我也试着比较了with
和acquire(), release()
语句的效率,发现前者比后者快一点,这是100次循环的结果如下。
"""with"""
for i in range(100): # with after for,
with self.lock:
self.target_fun(self.fun_args)
###### result ######
balance [0], total time [0.0022132000000000002]
subthread finishes
"""acquire & release """
for i in range(100):
self.lock.acquire()
self.target_fun(self.fun_args)
self.lock.release()
###### result ######
balance [0], total time [0.0035131000000000003]
subthread finishes
我正在学习 python3 多线程并尝试测试以下代码。代码所做的是使用多线程修改名为 test_change
的函数中的全局数字 balance
(初始值 = 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:
(请参阅 class 运行 函数中注释掉的部分)和 self.threadLock.acquire(), self.threadLock.release()
, 有没有人可以帮忙解释一下这个怪事。
您创建的每个线程都被赋予其 自己的 个 Lock()
实例,并且它们彼此无关。为了提供互斥,两个线程都必须使用 same Lock
对象。例如,在模块级别创建 Lock
的单个实例,并将其传递给线程的构造函数。
根据@Tim Peters 的建议,我将代码修改如下。
import time
import threading
from threading import Thread
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, lock, target_fun, fun_args, loop=False): # added a shared lock parameter
threading.Thread.__init__(self)
self.target_fun = target_fun
self.fun_args = fun_args
self.loop = loop
self.lock = lock # this is the shared lock
def run(self): # overwrite parent run function
if not self.loop:
self.target_fun(*self.fun_args)
elif self.loop:
for i in range(100):
with self.lock: # "with" after "for" so that both thread change the "balance" variable alternatively
self.target_fun(self.fun_args)
nums = [5, 12]
thread_list = []
thread_muduleLock = threading.Lock() # added a shared lock
start = time.perf_counter()
for i in range(2):
t = MyThread(thread_muduleLock, target_fun=test_change, fun_args=nums[i], loop=True) # passing the shared lock to the thread constructor
thread_list.append(t)
for i in range(len(thread_list)):
thread_list[i].start()
for i in range(len(thread_list)):
thread_list[i].join()
end = time.perf_counter()
total = end - start
print("balance [{}], total time [{}]".format(balance, total))
print("subthread finishes")
执行结果如下:
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-7, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
in Thread-6, balance is 0
balance [0], total time [0.1192338]
subthread finishes
除了上面那些,我也试着比较了with
和acquire(), release()
语句的效率,发现前者比后者快一点,这是100次循环的结果如下。
"""with"""
for i in range(100): # with after for,
with self.lock:
self.target_fun(self.fun_args)
###### result ######
balance [0], total time [0.0022132000000000002]
subthread finishes
"""acquire & release """
for i in range(100):
self.lock.acquire()
self.target_fun(self.fun_args)
self.lock.release()
###### result ######
balance [0], total time [0.0035131000000000003]
subthread finishes