Closed jerrychan807 closed 5 years ago
你的环境是什么? 我怀疑 Python3 的表现和 Python2 可能不一样。
以下,Python2 每次都会出现竞争条件,Python3 偶尔会出现:
➜ tmp python2.7 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 282
➜ tmp python2.7 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 1021
➜ tmp python2.7 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -4656
➜ tmp python3 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
➜ tmp python3 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
➜ tmp python3 test.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -56485
py2
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 602
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 955
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -4030
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 43
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -222
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -430
MacBook-Pro:p42 chanjerry$ python thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is -4503
py3
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
MacBook-Pro:p42 chanjerry$ python3 thread_lock.py
the value of shared variable with lock management is 0
the value of shared variable with race condition is 0
额,我这边python2也是每次都会出现竞争条件,Python3 不会出现,运行20+次以上,都不会出现条件竞争。
当把COUNT变大,设为100000时,py2和py3都会出现条件竞争.🙂
# -*- coding:utf-8 -*-
# @Time : 2018/12/15 4:44 PM
# @Author : jerry
import threading
shared_resource_with_no_lock = 0
COUNT = 100000
import time
#### NO LOCK MANAGEMENT
def increment_without_lock():
start = time.time()
global shared_resource_with_no_lock
for i in range(COUNT):
shared_resource_with_no_lock += 1
end = time.time()
print("increment:{0}".format(str(end - start)))
print('\n')
def decrement_without_lock():
start = time.time()
global shared_resource_with_no_lock
for i in range(COUNT):
shared_resource_with_no_lock -= 1
end = time.time()
print("decrement:{0}".format(str(end - start)))
if __name__ == '__main__':
t3 = threading.Thread(name='t3', target=increment_without_lock)
t4 = threading.Thread(name='t4', target=decrement_without_lock)
t3.start()
t4.start()
t3.join()
t4.join()
print("the value of shared variable with race condition is %s" % shared_resource_with_no_lock)
py2:
$ python2 thread_without_lock.py
decrement func use time:0.0448379516602
increment func use time:0.0543751716614
the value of shared variable with race condition is -6703
py3
$python3 thread_without_lock.py
increment func use time:0.00865316390991211
decrement func use time:0.00800633430480957
the value of shared variable with race condition is 0
t3.start() # t3 开始执行
t4.start() # t4 开始执行
t3.join() # 确保t3 结束
t4.join() # 确保t4 结束
py3运行速度更快?!🙂
在py3中,Count=100000,比较小时, t4.start()
来不及参与use shared memory的时候,t3任务结束了。
py3运行速度更快?!🙂
这个答案是肯定的,Python3 比 Python2 快。
Python3 的 GIL 机制效率更高一些,看下这里:https://www.reddit.com/r/Python/comments/4vyg2m/threadinglocking_is_4x_as_fast_on_python_3_vs/
至于为什么 Python3 出现竞争条件需要的时间更长,这个我也不太清楚。回去研究一下,要是搞明白的给你分享一下 :) 我猜可能也和 GIL 的新机制有关吧。
好呀,我有空也去研究下 谢谢啦~🙂
上一条可能有误导性,我更新了一下。我觉得可能有两种原因:
在我电脑上测试了一下,确实一旦 increment_without_lock
在 join 之前结束,最后结果就是 0;如果没结束,就不是。
讨论 GIL 实现机制我觉得意义不大,因为开发者不该关心 or rely on 这个。只要知道加锁避免就好了。
Hi Sorry for the late.
答案不会是 Python3 运行速度问题,而是 Python3 的 GIL 切换机制导致竞争条件出现的几率更小了(但是依然会出现),所以对于开发者来说没有什么用,该加锁的依然要枷锁。只不过平时测试测到竞争条件的几率更小了。
Raymond 这个视频很赞,里面讲到了 Python3 更难复现竞争条件: https://youtu.be/9zinZmE3Ogk?t=2487 以及提到了一个手动插入 FUZZY 的方法来测试。
新年快乐!
遇到的情况:
Run了书上Chapter2的Thread synchronization with lock and RLock的第一个例子
发现和书上的结果不一样.
预期是如果两个thread没加lock,去对shared memory操作时,会出现条件竞争.
代码:
运行结果:
在我的电脑上运行,当COUNT为100000时,运行几次后,结果都是一样的。
the value of shared variable with race condition is 0
.把COUNT变大,设置为1000000 才能出现预期的结果.
the value of shared variable with race condition is 1382
.我的看法:
t3
和t4
不是同时start
的 当Count比较小等于的时候,t3在t4.start()
之前已经结束了,把全局的shared_resource_with_no_lock
加到100000了,这个时候
t4.start()
了,把全局的shared_resource_with_no_lock
减回到0了,最终输出结果是
the value of shared variable with race condition is 0
. 此时并没有出现预期的条件竞争.只有当Count足够大,以至于,t3在
t4.start()
之前,这个很短的时间内不能run完,才会出现预期的条件竞争,导致最终的输出结果不为0看来这个跟运行机器的性能有关系呀~
不知道我的理解是否正确? please help~