Как создать новый каталог в Python одновременно из разных процессов? - PullRequest
0 голосов
/ 19 марта 2019

Первое, что делает мой скрипт на python, это создает выходной каталог:

def create_output_directory():
    # creating output folder and link to latest
    output_folder = 'output_%s' % datetime.now().strftime('%Y%m%d')
    if os.path.exists(output_folder):
        logger.warning('previous directory %s exists, file will be overwritten' % output_folder)
    else:
        os.mkdir(output_folder)
    if os.path.exists('output_latest'):
        os.remove('output_latest')
    os.symlink(output_folder, 'output_latest')
    return output_folder

, чтобы вы получили пустой каталог output_20190319 и символическую ссылку output_latest на него.

Я хочу параллельно запускать разные экземпляры моего скрипта Python с разными аргументами.В сценарии оболочки:

python myscript.py arg1 &
sleep 1
python myscript.py arg2 &
sleep 1
python myscript.py arg3 &

обычно это работает без проблем, но иногда я получаю:

  File "myscript.py", line 16, in create_output_directory                                                                                                                      
      os.mkdir(output_folder)                                                                                                                                                                                        
OSError: [Errno 17] File exists: 'output_20190319'    

Я не уверен, что понимаю.Разве не достаточно 1 секунды, чтобы создать каталог и избежать условий гонки?Есть ли лучшее решение?Блокировка файла?

1 Ответ

0 голосов
/ 19 марта 2019

Одной секунды недостаточно.

Попытка:

str(os.getpid())

Так что для удобства чтения:

output_folder = 'output_%s' % str(os.getpid())

По-прежнему технически возможно, чтобы два процесса работали подряд с одним и тем же pid, если они работают быстро, поэтому, если один пришел и ушел, а следующий экземпляр пришел с тем же pid, вы получите еще одно столкновение. Возможно, рассмотрим модуль tempfile.

Затем вернемся к:

output_folder = 'output_%s_%s' % (datetime.now().strftime('%Y%m%d'), str(os.getpid()))

Для аналогичной необходимости я реализовал попытку / за исключением тех случаев, когда он повторяет попытки, пока не получит уникальное имя, спит короткое время между повторными попытками, в моем случае мне нужно было определенное имя без случайных строк. Ничего элегантного в этом нет, я написал это быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...