Нужна ли Python Queue для простого потока байтов между потоками?
-
08-07-2019 - |
Вопрос
У меня есть простой поток, который извлекает байты из гнезда Bluetooth RFCOMM (похожего на последовательный порт) и выгружает их в Queue.Queue
(FIFO), который выглядит как типичный метод обмена данные между потоками. Работает нормально.
Это перебор? Могу ли я просто использовать bytearray, тогда у моего потока чтения .append (somebyte)
и функции обработки просто .pop (0)
? Я не уверен, предназначены ли средства защиты в очереди для более сложных «многопользовательских, многопользовательских очередей»; и пустая трата для потока байтов точка-точка. Такие вещи, как очистка очереди или захват нескольких байтов, кажутся более неудобными в сравнении с очередью и более простым типом данных.
Я думаю, что ответ может быть связан с тем, что .pop ()
является атомарным, но будет ли это тогда иметь значение? ...
Решение
С Queue
вы гарантированно гарантируете многопоточность в любой реализации и версии Python. Опираясь на тот или иной метод, когда какой-то другой объект является «атомным» (в данной реализации и версии) обычно оставляет вас во власти этого «атомарности» не является сильной гарантией (просто артефактом реализации для конкретной конкретной версии и используемой вами версии) и, следовательно, неуловимыми, ОЧЕНЬ трудными для отладки условиями гонки, вводимыми при любом обновлении или переносе на другие реализации Python.
Если ваше профилирование говорит вам, что строгие и общие гарантии Queue
являются узким местом для вашего конкретного случая использования производителем-потребителем, создайте свою собственную более простую очередь FIFO с гарантией безопасности потока / поток. Например, если вы узнали, что (без учета условий гонки) append
и pop
идеально подходят для вашего использования, просто создайте класс, который защищает каждого с помощью блокировки приобретение / освобождение (используйте оператор with
) - Queue
добавляет минимальные накладные расходы для поддержки нескольких производителей и потребителей, и вы можете сократить эти несколько наносекунд! -)
Другие советы
Да, pop () является атомарным, но я бы придерживался Queue, если производительность не так важна. Р>
Если скорость ввода достаточно высока, вы всегда можете буферизовать байты в строку, прежде чем поместить ее в очередь. Это, вероятно, увеличит пропускную способность за счет уменьшения объема выполняемой блокировки за счет небольшой дополнительной задержки на принимающей стороне.