Domanda

Ho un semplice thread che prende byte da un socket RFCOMM Bluetooth (simile a una porta seriale) e li scarica in un Queue.Queue (FIFO), che sembra il metodo tipico per lo scambio dati tra thread. Funziona bene.

Ma questo è eccessivo? Potrei semplicemente usare un bytearray e avere il mio thread del lettore .append (somebyte) e la funzione di elaborazione solo .pop (0) ? Non sono sicuro che le protezioni in Queue siano pensate per code "multi-produttore, multi-consumatore" più complesse e uno spreco per un flusso di byte da punto a punto. Fare cose come svuotare la coda o catturare più byte sembra più imbarazzante con la coda rispetto a un tipo di dati più semplice.

Suppongo che la risposta potrebbe avere a che fare se .pop () è atomico, ma importerebbe anche allora? ...

È stato utile?

Soluzione

Con Queue , sei garantito di essere thread-safe in qualsiasi implementazione e versione di Python. Basandosi su questo o quel metodo di un altro oggetto che è "atomico" (in una data implementazione e versione) in genere ti lascia in balia di questa "atomicità" non essendo una garanzia forte (solo un artefatto di implementazione per lo specifico rilascio di punti e amp; c che stai usando) e quindi condizioni di gara MOLTO difficili da mettere in debutto che vengono introdotte con qualsiasi aggiornamento o porta ad altre implementazioni di Python.

Se la tua profilazione ti dice che le garanzie forti e generali di Queue rappresentano un collo di bottiglia per il tuo specifico caso d'uso produttore-consumatore, rendi la tua coda FIFO più sicura garantita da thread / ruscello. Ad esempio, se hai scoperto che (al netto delle condizioni di gara) append e pop sarebbero perfetti per il tuo uso, crea una classe che protegga ciascuno con un lucchetto acquisisci / rilascia (usa una con ) - Queue aggiunge un sovraccarico minuscolo per supportare più produttori e consumatori e puoi eliminare quei pochi nanosecondi! -)

Altri suggerimenti

Sì, pop () è atomico, ma resterei fedele a Queue se le prestazioni non sono molto importanti.

Se la velocità di input è abbastanza veloce, puoi sempre bufferizzare i byte in una stringa prima di spingerli nella coda. Ciò probabilmente aumenterà il throughput riducendo la quantità di blocchi effettuati, a scapito di un po 'di latenza aggiuntiva sul lato ricevente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top