2012-01-09 16 views
6

Ho provato su google, non ho trovato risposta, cercato qui, non ho trovato risposta. Qualcuno ha esaminato se è thread-safe scrivere su un oggetto Serial() (pyserial) dal thread a ed effettua il blocco delle letture dal thread b?pyserial - è possibile scrivere sulla porta seriale dal thread a, bloccare le letture dal thread b?

So usare le primitive di sincronizzazione dei thread e le strutture di dati thread-safe, e in effetti la mia forma attuale di questo programma ha una thread dedicata alla lettura/scrittura sulla porta seriale e utilizzo strutture di dati thread-safe per coordinare attività nell'app.

La mia app sarebbe di grande utilità se potessi scrivere sulla porta seriale dal thread principale (e non leggerlo mai), e leggere dalla porta seriale usando il blocco delle letture nel secondo thread (e mai scrivere ad esso). Se qualcuno vuole davvero che io entri nel motivo per cui ciò avvantaggerebbe l'app, posso aggiungere le mie ragioni. Nella mia mente ci sarebbe solo un'istanza di Serial() e anche mentre il thread B si trova in una lettura di blocco sull'oggetto Serial, il thread A sarebbe sicuro di usare metodi di scrittura sull'oggetto Serial.

Qualcuno sa se la classe Serial può essere utilizzata in questo modo?

MODIFICA: Mi viene in mente che la risposta può dipendere dalla piattaforma. Se hai esperienza con una piattaforma come questa, sarebbe bene sapere su quale piattaforma stavi lavorando.

EDIT: C'è stata solo una risposta, ma se qualcun altro ha provato questo, si prega di lasciare una risposta con la vostra esperienza.

risposta

11

Ho fatto questo con Pyserial. Leggere da un thread e scrivere da un altro non dovrebbe causare problemi in generale, poiché non esiste in realtà alcun tipo di problema di arbitraggio delle risorse. Le porte seriali sono full duplex, quindi la lettura e la scrittura possono avvenire in modo completamente indipendente e allo stesso tempo.

+0

Stavi usando PySerial? E su quali piattaforme ha funzionato correttamente? –

+0

Stavo usando PySerial su Windows, ma non riesco a immaginare perché non funzionerebbe su nessuna piattaforma. – TJD

+0

Grazie per aver condiviso la tua esperienza! –

3

Ho usato pyserial in questo modo su Linux (e Windows), nessun problema!

0

Si consiglia di modificare il thread B da "blocking read" a "non blocking read/write". Thread B diventerebbe la tua porta seriale "Daemon".

Il thread A può funzionare a piena velocità per un'interfaccia utente intuitiva o eseguire qualsiasi operazione in tempo reale.

Il thread A scriverebbe un messaggio su Thread B invece di provare a scrivere direttamente sulla porta seriale. Se la dimensione/frequenza dei messaggi è bassa, un semplice buffer condiviso per il messaggio stesso e un flag per indicare che un nuovo messaggio è presente funzionerebbe. Se hai bisogno di prestazioni più elevate, dovresti usare una pila. Questo è in realtà implementato semplicemente usando un array abbastanza grande da accumulare molti messaggi da inviare e due puntatori. Il puntatore di scrittura viene aggiornato solo dal thread A. Il puntatore di lettura viene aggiornato solo dal thread B.

Il thread B recupera il messaggio e lo invia alla porta seriale. La porta seriale deve utilizzare la funzione di timeout in modo che la funzione di porta seriale di lettura rilasci la CPU, consentendo di eseguire il polling del buffer condiviso e, se è presente un nuovo messaggio, inviarlo alla porta seriale. A quel punto userei un sleep per limitare il tempo di CPU usato dal Thread B. Quindi, puoi fare il loop di Thread B alla funzione di lettura della porta seriale. Se il timeout della porta seriale non funziona correttamente, come se il cavo USB-RS232 fosse scollegato, la funzione sleep farà la differenza tra un buon codice Python e uno non così buono.

+4

L'intero punto dell'approccio a due thread è che non è necessario avere il polling da nessuna parte, poiché il thread del lettore si blocca solo su rcv. – mikepurvis

Problemi correlati