Запись в один и тот же файл (ы) с многопроцессорной обработкой (избегайте блокировки) - PullRequest
1 голос
/ 12 июня 2019

Я запускаю скрипт для нескольких CSV-файлов, используя многопроцессорность.
Если строка соответствует регулярному выражению, она записывает строку в (a) новый файл (ы) (новое имя файла равно совпадению).
Я заметил проблему записи в один и тот же файл (ы) из разных процессов (блокировка файла). Как я могу это исправить?

Мой код:

import re
import glob
import os
import multiprocessing

pattern ='abc|def|ghi|jkl|mno'
regex = re.compile(pattern, re.IGNORECASE)

def process_files (file):
    res_path = r'd:\results'
    with open(file, 'r+', buffering=1) as ifile:
        for line in ifile:
            matches = set(regex.findall(line))
            for match in matches:
                res_file = os.path.join(res_path, match + '.csv') 
                with open(res_file, 'a') as rf:
                    rf.write(line)

def main():

    p = multiprocessing.Pool()
    for file in glob.iglob(r'D:\csv_files\**\*.csv', recursive=True):
        p.apply_async(process, [file]) 

    p.close()
    p.join()

if __name__ == '__main__':
    main()

Заранее спасибо!

1 Ответ

3 голосов
/ 12 июня 2019

Сделать имя файла уникальным для каждого подпроцесса:

def process_files (file, id):
    res_path = r'd:\results'
    for line in file:
        matches = set(regex.findall(line))
        for match in matches:
            filename = "{}_{}.csv".format(match, id)
            res_file = os.path.join(res_path, filename) 
            with open(res_file, 'a') as rf:
                rf.write(line)

def main():

    p = multiprocessing.Pool()
    for id, file in enumerate(glob.iglob(r'D:\csv_files\**\*.csv', recursive=True)):
        p.apply_async(process, [file, id]) 

тогда вам нужно будет добавить код для объединения различных файлов "_.csv" в один файл ".csv".

Одновременная запись в один и тот же файл - это то, чего вы хотите избежать - либо у вас нет блокировок файлов, и вы в конечном итоге получаете поврежденные данные, либо у вас есть блокировки файлов, и тогда это замедлит процесс, который повредит весь процесс. точка распараллеливания.

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