wangwh27 发表于 2022-12-6 16:44

多线程案例python3.8和3.10运行结果不一致

import threading


total = 0


def add():
    global total
    for i in range(10000000):
      total += 1


def desc():
    global total
    for i in range(10000000):
      total -= 1


thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(total)

Python3高级核心技术97讲课程中,多线程的一个案例,在python3.8版本中,total最终结果是随机的,不为0,但是换成python3.10或者3.11版本,结果总是为0,非常奇怪,求大佬解答。

hecoter12138 发表于 2022-12-6 23:07

因为执行速度不一样,子线程都没执行完就输出结果了,你这线程写的很有问题

黑色小白 发表于 2022-12-6 23:16

3.10 修复另一个bug导致的看起来线程安全了实际还是不安全的

hrpzcf 发表于 2022-12-6 23:49

应该是 3.10 以下的 BUG,理论上 3.10、3,11的结果才是对的,给代码上锁以后,使用 3.8 执行,结果也是 0
import threading


total = 0
lock = threading.Lock()


def add():
    global total
    for i in range(10000000):
      lock.acquire()
      total += 1
      lock.release()


def desc():
    global total
    for i in range(10000000):
      lock.acquire()
      total -= 1
      lock.release()


thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(total)

李玉风我爱你 发表于 2022-12-7 09:11

import threading

total = 0


def add():
    global total
    for i in range(10000000):
      total += 1


def desc():
    global total
    for i in range(10000000):
      total -= 1

threads = []
t1 = threading.Thread(target=add)
t2 = threading.Thread(target=desc)
threads.append(t1)
threads.append(t2)
for t in threads:
    t.start()
    t.join()
print(total)

李玉风我爱你 发表于 2022-12-7 09:15

import threading

total = 0


def add():
    global total
    for i in range(10000000):
      total += 1


def desc():
    global total
    for i in range(10000000):
      total -= 1

# threads = []
# t1 = threading.Thread(target=add)
# t2 = threading.Thread(target=desc)
# threads.append(t1)
# threads.append(t2)
# for t in threads:
#   t.start()
#   t.join()
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
# thread2.start()
thread1.join()
thread2.start()
thread2.join()
# time.sleep(10)
print(total)

xxl1039 发表于 2022-12-7 09:24

线程不能共享全局变量了,像不安全的。

wangwh27 发表于 2022-12-7 14:38

黑色小白 发表于 2022-12-6 23:16
3.10 修复另一个bug导致的看起来线程安全了实际还是不安全的

请教大佬,3.10以上版本具体修复了什么bug,导致这种情况看起来是线程安全的?

黑色小白 发表于 2022-12-7 21:34

wangwh27 发表于 2022-12-7 14:38
请教大佬,3.10以上版本具体修复了什么bug,导致这种情况看起来是线程安全的?

https://github.com/python/cpython/commit/4958f5d69dd2bf86866c43491caf72f774ddec97
页: [1]
查看完整版本: 多线程案例python3.8和3.10运行结果不一致