我正在尝试升级在Windows上运行可执行文件的python脚本,并将文本输出文件管理为使用多个线程进程的版本,以便我可以使用多个核心。我有四个单独的可执行文件版本,每个线程都知道可以访问。这部分工作正常。遇到问题的地方是它们同时运行并尝试打开(不同的)输出文件以确保它们正确运行并根据输出文件的内容做出反应。
具体来说,当运行三个线程时,两个线程会因以下错误而崩溃,而其中一个仍继续工作:
Exception in thread Thread-4:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 552, in __bootstrap_inner
self.run()
File "E:\HDA\HDA-1.0.1\Hm-1.0.1.py", line 782, in run
conf = self.conf_file(Run)
File "E:\HDA\HDA-1.0.1\Hm-1.0.1.py", line 729, in conf_file
l = open(self.run_dir(Run)+Run, 'r').readlines() #list of file lines
IOError: [Errno 2] No such file or directory: 'Path/to/Outputfile'
这是因为线程未正确运行可执行文件(即为什么'Path / to / Outputfile'未创建,因此无法找到)。但其中一个线程正确地执行此操作,而其他两个线程不能。我有没有理由不能让多个线程运行不同版本的可执行文件?
答案 0 :(得分:2)
我不认为GIL本身不会自行杀死它,除非打开文件会让你陷入一些奇怪的死锁或自旋锁状态。 一般情况下,在 O绑定的情况下,想要线程。实际上,线程能够并发运行这一事实可能会导致其他线程失败,而不是多次成功打开文件。
On slide fifteen of this presentation,作者指出GIL发布阻止I / O调用以给其他线程一个机会。
这里真正的问题似乎是对文件资源的锁定。我不太确定Windows是如何工作的,所以我不能说出为什么这个错误正在蔓延,但似乎只有一个线程实际上锁定了文件资源。
关于多个内核和GIL的另一个海报可能会发挥作用,因为你可能会在其他两个线程变得饥饿的情况下进行某种优先级反转,但我发现上述表示不太可能说阻塞操作中间的线程释放了其他线程的锁。
一种想法是尝试multiprocessing
。我怀疑你在多个进程中读取文件而不是使用线程会有更好的运气。
以下是我在OS 10.7.3计算机上编写并尝试的示例,它打开了一个文件test
,其内容为lol\n
:
import multiprocessing
import os
def open_file(x):
with open(x, 'r') as file_obj:
return file_obj.readlines()
a = multiprocessing.Pool(4)
print a.map(open_file, ['test']*4)
这是我执行时的结果:
➜ ~ git:(master) ✗ python open_test.py
[['lol\n'], ['lol\n'], ['lol\n'], ['lol\n']]
答案 1 :(得分:1)
由于Global Interpreter Lock,Python目前无法利用多个核心。多线程往往充满麻烦,无论如何 - 如果可以,最好使用多个进程。