本帖最后由 井右寺 于 2019-8-24 20:18 编辑
这个坑,已经趟过无数次了....
然而下次遇到了,还是习惯错误的写法,记录一下,也给大家提个醒——
测试例子如下,猜一下最后输出会是什么,和最后结果会不会有差异
[Python] 纯文本查看 复制代码 import time
import threading
def test(i,count, _type):
time.sleep(3)
if lock.acquire():
if type(count) == int:
count += 1
else:
count[0] += 1
lock.release()
print(_type, ":", i, count)
if __name__ == '__main__':
threads = []
lock = threading.Lock()
# 情况一
cnt = 0
for i in range(3):
threads.append(threading.Thread(target=test, args=(i,cnt, "type 1")))
# 情况二
cnt2 = [0]
for j in range(3,6):
threads.append(threading.Thread(target=lambda: test(j, cnt2, "type 2")))
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
# 这是几
print(cnt)
# 这又是几
print(cnt2)
input("end!")
——————————————————————————分割线————————————————————————————————
打印结果应该如下(线程完成时间可能有差异,这个不影响)
[HTML] 纯文本查看 复制代码 type 1: 0 1
type 1: 1 1
type 1: 2 1
type 2: 5 [1]
type 2: 5 [2]
type 2: 5 [3]
0
[3]
和你想的有没有差距呢?
涉及到的原因:
1、lambda返回的是一个匿名函数,而不是函数执行。在实际start执行的时候才进行的lambda表达式的执行,这个时候 j已经成为了5。
2、值传递和引用传递的问题,简单类型会进行值传递,复杂类型才会进行引用传递。int为简单类型,值被传递进去,所以函数外的变量未被修改,而array为复杂类型,把引用传递进去了,函数会影响参数变量。
|