2016-11-01 2 views
0

У меня есть много файлов на диске, которые нужно читать, первый вариант использует многопоточность, он отлично работает на SSD. (когда потоки заблокированы IO, он отпустит GIL)многопоточность python читает обход буфера памяти только для чтения GIL

Но я хочу добиться такой же или более быстрой скорости без SSD, поэтому я предварительно загружаю их в память (например, в хранилище в dict), и каждый поток будет читать каждый файл содержимое из памяти. К сожалению, возможно, из-за GIL существует блокировка в dict, поэтому его скорость еще медленнее, чем загрузка файлов с SSD!

Итак, мой вопрос в том, что есть ли какое-либо решение, которое может создать буфер памяти только для чтения без блокировки/GIL? как ramdisk или что-то еще>

+0

Если вы действительно хотите как можно больше скорости, как насчет переписывания вашей программы (или, по крайней мере, ее критически важных частей) на C или C++ или на какой-либо другой полностью скомпилированный язык? Тогда у вас не будет GIL, а также никаких накладных расходов на переводчика, поскольку вы будете запускать собственный исполняемый файл. –

ответ

1

Короче говоря, нет.

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

(Особая благодарность Graham Dumpleton!) Один из solution - это написать C-расширения для CPython. И выпустите GIL, когда войдете в «царство C». Просто будьте осторожны, чтобы вы не могли получить доступ к материалам python без защиты GIL, иначе это вызовет тонкие ошибки или сбой непосредственно.

Существует несколько реализаций, которые не используют GIL, например Jython и Cython. Вы можете попробовать их использовать. Но писать правильную многопоточную программу сложно. Написание быстрой многопоточной программы еще сложнее. Мое предложение состоит в том, чтобы написать многопроцессорную программу вместо multithread. И передавать данные через IPC или так (допустим, ZeroMQ, он прост в использовании и быстро).

+1

Не совсем. Поскольку потоки C используются под обложкой в ​​CPython, технически несколько потоков все еще могут работать, но только один из них будет разрешен одновременно для запуска кода Python. Так тонкая разница в том, что вы описываете. Использование C-расширений для CPython, если для данных, которые им необходимы для работы, не требуется блокировка глобального интерпретатора Python для объектов данных Python, то несколько потоков могут успешно работать одновременно. –

+0

Спасибо за исправление! Позвольте мне переписать тогда ;-) – HKTonyLee

0

Позвольте мне добавить несколько вопросов к ответу @HKTonyLee.

Итак, у Python есть этот GIL. Но он освобождается при выполнении, например, ввода-вывода файлов. Это означает, что вы можете параллельно читать файлы. Поскольку с точки зрения процессов нет такой вещи, как файл, но только файловые дескрипторы (предполагается, что posix), то все, что вы читаете, не нужно хранить на диске.

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

Смежные вопросы