2

我正在尝试将在 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'

这是由于线程未正确运行可执行文件造成的(即为什么没有创建“路径/到/输出文件”,因此无法找到)。但是其中一个线程可以正确执行此操作,而其他两个线程则不能。为什么我不能让多个线程运行不同版本的可执行文件有什么原因?

4

2 回答 2

2

由于Global Interpreter Lock,Python 目前无法利用多个内核。无论如何,多线程往往充满了麻烦——如果可以的话,最好使用多个进程。

于 2012-04-25T02:04:39.133 回答
2

我不认为 GIL 本身不会自己杀死它,除非打开文件会让你陷入一些奇怪的死锁或自旋锁状态。 一般来说,在这种情况下,你需要线程,因为你是 I/O-bound 。事实上,线程能够同时运行的事实可能会导致其他线程失败,而不是多次成功打开文件。

在本演示文稿的第十五张幻灯片中,作者指出 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']]
于 2012-04-25T05:57:21.333 回答