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

казали, что ведение журнала не может быть использовано в многопроцессорной. Вы должны выполнить управление параллелизмом в случае, если многопроцессорность испортит журнал.

Но я сделал несколько тестов, кажется, нет проблем с использованием входа в многопроцессорную

Как видно из кода.

Я намеренно позволил подпроцессу записывать журнал в тот же момент (5 секунд после запуска), чтобы увеличить вероятность конфликта. Но конфликта нет вообще.

Итак, мой вопрос: можем ли мы использовать ведение журнала в многопроцессорной среде? Почему так много постов сказать не можем?

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

Теперь происходит то, что каждый процесс содержит дескриптор открытого файла и выполняет «добавочную запись» в этот файл. Вопрос в том, при каких обстоятельствах запись добавления является «атомарной» (то есть не может быть прервана, например, другим процессом, записывающим в тот же файл и смешивающим его выходные данные). Эта проблема относится ко всем языкам программирования, так как в конце они будут выполнять системный вызов ядра.[Этот ответ](https://stackoverflow.com/questions/1154446/is-file-append-atomic-in-unix) ответы, при каких обстоятельствах общий файл журнала в порядке.

Все сводится к проверке размера буфера канала в Linux, который определен в`/usr/include/linux/limits.h` и составляет 4096 байт. Для других ОС вы найдете[Вот](http://ar.to/notes/posix#pipe-buf) хороший список

Это означает: если ваша строка журнала меньше 4'096 байт (если в Linux), то добавление безопасно, если диск подключен напрямую (т.е. между сетями нет). Но для более подробной информации, пожалуйста, проверьте первую ссылку в моем ответе. Чтобы проверить это вы можете сделать`logger.info('proc name %s id %s %s' % (proc.name, proc.pid, str(proc.name)*5000))` с разными длинами. С 5000 например я уже перепутал строки журнала в`/tmp/test.log`.

В[этот вопрос](https://stackoverflow.com/questions/641420/how-should-i-log-while-using-multiprocessing-in-python) уже есть довольно много решений для этого, поэтому я не буду добавлять свое собственное решение здесь.

**Обновление: колба и многопроцессорность**

Веб-фреймворки, такие как flask, будут работать на нескольких рабочих, если они размещены в uwsgi или nginx. В этом случае несколько процессов могут записывать в один файл журнала. У него будут проблемы?

Обработка ошибок в флешке выполняется через stdout / stderr, который затем перехватывается веб-сервером (uwsgi, nginx и т. Д.), Который должен следить за тем, чтобы логи записывались правильно (см., Например, [этот пример фляги + nginx]) (<http://flaviusim.com/blog/Deploying-Flask-with-nginx-uWSGI-and-Supervisor/>), возможно, также добавляя информацию о процессах, чтобы можно было связать строки ошибок с процессами. Из[фляги док](http://flask.pocoo.org/docs/0.12/errorhandling/#logging-to-a-file):

По умолчанию, начиная с Flask 0.11, ошибки регистрируются в журнале вашего веб-сервера автоматически. Предупреждений однако нет.

Таким образом, у вас все еще будет проблема смешанных файлов журнала, если вы используете`warn` и сообщение превышает размер буфера канала.



Согласно с<https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes>

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

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

Тогда вам просто нужно позвонить`addHandler`:



ения после ошибок, передавая все в родительский процесс через канал.

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