Файл не может быть найден, когда я использую #Fabric put# в многопоточности для копирования временного файла, созданного tempfile.mkstemp, в удаленный файл

#python #multithreading #fabric #put #mkstemp

#python #многопоточность #fabric #поместите #mkstemp

Вопрос:

Версия Python: 2.6.4

Версия Fabric: 1.9.0

У меня есть платформа тестирования автоматизации для параллельного выполнения обращений с использованием многопоточности.Поток (3 потока в моем случае).

Каждый рабочий поток использует fabric put (хотя мы делаем некоторую оболочку для этой функции), чтобы скопировать временный файл, созданный tempfile.mkstemp, в удаленный файл.

Вопрос в том, что он всегда выдает мне сообщение об ошибке, что файл не может быть найден, ошибка возникает во время «ввода» из подсказок об исключениях.

вот код при выполнении ‘put’:

MyShell.py (Родительский класс MyFabShell)

 def putFileContents(self, file, contents):

    fd, tmpFile= tempfile.mkstemp()

    os.system('chmod 777 %s' % tmpFile)

    contentsFile = open(tmpFile, 'w')
    contentsFile.write(contents)
    contentsFile.close()

    dstTmpFile = self.genTempFile()

    localshell = getLocalShell()

    self.get(localshell, tmpFile, dstTmpFile) # use local shell to put tmpFile to dstTmpFile


    os.close(fd)

    os.remove(tmpFile)
    #os.remove(tmpFile)
  

MyFabShell.py:

 def get( self, srcShell, srcPath, dstPath ):
    srcShell.put( self, srcPath, dstPath )

def put(self, dstShell, srcpath, dstpath):

    if not self.pathExists( srcPath ):  # line 158
        raise Exception( "Cannot put <%s>, does not exist." % srcPath )

    # do fabric get/put in the following
    # ...
  

Вызов put приводит к ошибке:

 ...
self.shell.putFileContents(configFile, contents)
File "/path/to/MyShell.py", line 401, in putFileContents
self.get(localShell, tmpFile, dstTmpFile)
File "/path/to/MyFabShell.py", line 134, in get
srcShell.put( self, srcPath, dstPath )
File "/path/to/myFabShell.py", line 158, in put
raise Exception( "Cannot put <%s>, does not exist." % srcPath )
Exception: Cannot put </tmp/tmpwt3hoO>, does not exist.
  

Изначально я сомневаюсь, что файл может быть удален во put время, поэтому я прокомментировал os.remove . Однако я снова получил ту же ошибку.
Из журнала исключений это не должно быть проблемой «fabric put», поскольку исключение возникает перед выполнением fabric get / put
mkstemp Небезопасно ли использовать многопоточность? но в документе говорится, что «При создании файла нет условий гонки» или мой случай терпит неудачу из-за GIL? Я подозреваю, что это связано с тем, что, когда я использую только 1 поток, все будет хорошо.

Кто-нибудь может дать мне подсказку о моей ошибке? Некоторое время я боролся с проблемой: (

Комментарии:

1. Когда происходит обработка потоков? Этот код уже находится в потоке, или это происходит в myput ? Также не могли бы вы указать трассировку стека? И / или общее представление о том, что происходит в вашей оболочке?

2. Спасибо @Morgan, я уточнил свои вопросы с помощью кода режима, а также журналов.

3. Моя проблема решается, когда я явно «присоединяюсь» к потоку. все мои потоки не являются потоками демонов, и каждый из потоков выполняет большую часть операций ввода-вывода (например, запись / чтение файла). ‘join’ явно гарантирует, что задание каждого потока завершено. Я все еще не уверен в основной причине моей проблемы … временный файл на самом деле существует, но поток жалуется «не удается найти», единственное предположение, которое я могу дать, это то, что мы всегда должны явно присоединяться, особенно когда ваше задание потока связано с операцией ввода-вывода?

Ответ №1:

Моя проблема решается, когда я явно «присоединяюсь» к потоку. все мои потоки не являются потоками демонов, и каждый из потоков выполняет большую часть операций ввода-вывода (например, запись / чтение файла). ‘join’ явно гарантирует, что задание каждого потока завершено. Я все еще не уверен в основной причине моей проблемы … временный файл на самом деле существует, но поток жалуется на «не удается найти», когда несколько потоков работают вместе, единственное предположение, которое я могу дать: когда поток A выполняет операцию ввода-вывода, поток A освобождает GIL, чтобы потокB (или C, D …) может получить GIL во время операции ввода-вывода. проблема может возникнуть во время ввода-вывода, потому что поток A больше не находится в интерпретаторе Python … вот почему «файл не может быть найден» с помощью A, однако, когда мы явно присоединяемся к A, A всегда обязательно завершает свою работу, повторно вводя GI (глобальный интерпретатор).