Uma fila Python é necessária para um fluxo de bytes simples entre os threads?
-
08-07-2019 - |
Pergunta
Eu tenho um fio simples que pega bytes de um soquete Bluetooth RFComm (tipo serial-port) e os despeja em um Queue.Queue
(FIFO), que parece ser o método típico de trocar dados entre os threads. Funciona bem.
Isso é exagerado? Eu poderia apenas usar um bytearray e depois ter meu tópico do leitor .append(somebyte)
e a função de processamento apenas .pop(0)
? Não tenho certeza se as proteções na fila são destinadas a filas mais complexas de "multi-produtor e multi-consumidor" e um desperdício para um fluxo de bytes ponto a ponto. Fazer coisas como lavar a fila ou pegar vários bytes parece mais estranho com a fila versus um tipo de dados mais simples.
Eu acho que a resposta pode ter a ver se .pop()
Atomic, mas isso importa então? ...
Solução
Com Queue
, você é garantido ser threadSafe em qualquer implementação e versão do Python. Contar com esse ou aquele método de algum outro objeto sendo "atômico" (em uma determinada implementação e versão) normalmente deixa você à mercê dessa "atomicidade" não sendo uma garantia forte (apenas um artefato de implementação para a liberação específica de ponto & c you you 'Usando) e, portanto, as condições de corrida sutis e muito difíceis de estrear com qualquer atualização ou porta para outras implementações do Python.
Se o seu perfil lhe disser isso Queue
As garantias fortes e gerais de Geral estão sendo um gargalo para o seu caso de uso específico do produtor-consumidor, faça com que sua própria fila/fluxo mais simples garantida para ser threadsafe FIFO. Por exemplo, se você descobriu isso (líquido de condições de corrida) append
e pop
Seria perfeito para o seu uso, basta fazer uma aula que proteja cada um com um bloqueio de aquisição/liberação (use um with
declaração) -- Queue
Adiciona uma sobrecarga minúscula para apoiar vários produtores e consumidores e você pode raspar esses poucos nanossegundos!-)
Outras dicas
Sim, o pop () é atômico, mas eu ficaria na fila se o desempenho não for super importante.
Se a taxa de entrada for rápida o suficiente, você sempre poderá amortecer bytes em uma string antes de empurrá -la na fila. Isso provavelmente aumentará a taxa de transferência, reduzindo a quantidade de bloqueio, às custas de uma pequena latência extra na extremidade de recebimento.