Zad*_*org 28 python multithreading python-multithreading python-internals
对于一些简单的线程相关代码,即:
\nimport threading\n\n\na = 0\nthreads = []\n\n\ndef x():\n global a\n for i in range(1_000_000):\n a += 1\n\n\nfor _ in range(10):\n thread = threading.Thread(target=x)\n threads.append(thread)\n thread.start()\n\n\nfor thread in threads:\n thread.join()\n\n\nprint(a)\nassert a == 10_000_000\nRun Code Online (Sandbox Code Playgroud)\n根据 Python 版本,我们得到了不同的行为。
\n对于 3.10,输出为:
\n\xe2\x9d\xaf python3.10 b.py\n10000000\nRun Code Online (Sandbox Code Playgroud)\n对于 3.9,输出为:
\n\xe2\x9d\xaf python3.9 b.py\n2440951\nTraceback (most recent call last):\n File "/Users/romka/t/threads-test/b.py", line 24, in <module>\n assert a == 10_000_000\nAssertionError\nRun Code Online (Sandbox Code Playgroud)\n由于我们没有获取任何锁,对我来说,3.9 的结果是显而易见的并且是预期的。问题是为什么 3.10 得到了“正确”的结果,而不应该得到“正确”的结果?
\n我正在查看 Python 3.10 的变更日志,没有任何与线程或 GIL 相关的内容可以带来这样的结果。
\nNed*_*der 25
Mark Shannon 重构快速操作码调度的更改的意外后果:https://github.com/python/cpython/commit/4958f5d69dd2bf86866c43491caf72f774ddec97 - INPLACE_ADD 操作码不再使用检查中断等的“慢速”调度路径。