pyserial - можно записать в последовательный порт из потока a, блокировка чтения из потока b? - PullRequest
8 голосов
/ 10 января 2012

Я попытался погуглить, не смог найти ответ, искал здесь, не мог найти ответ.Кто-нибудь изучал, является ли это потокобезопасным для записи в объект Serial () (pyserial) из потока a и блокирования чтения из потока b?

Я знаю, как использовать примитивы синхронизации потоков и структуры потоков, безопасные для потокови фактически моя текущая форма этой программы имеет поток, предназначенный для чтения / записи через последовательный порт, и я использую поточно-ориентированные структуры данных для координации действий в приложении.

Мое приложение получит большую выгоду, если ямог записывать в последовательный порт из основного потока (и никогда не читать из него) и читать из последовательного порта, используя блокировку чтения во втором потоке (и никогда не записывать в него).Если кто-то действительно хочет, чтобы я объяснил, почему это принесет пользу приложению, я могу добавить свои причины.На мой взгляд, будет только один экземпляр Serial (), и даже когда поток B находится в блокирующем чтении для объекта Serial, поток A будет безопасно использовать методы записи для объекта Serial.

Кто-нибудь знаетможно ли использовать класс Serial таким образом?

РЕДАКТИРОВАТЬ: мне приходит в голову, что ответ может зависеть от платформы.Если у вас есть опыт работы с такой платформой, было бы хорошо узнать, на какой платформе вы работали.

РЕДАКТИРОВАТЬ: Был только один ответ, но если кто-то попробовал это, пожалуйста, оставьте ответс вашим опытом.

Ответы [ 4 ]

12 голосов
/ 10 января 2012

Я сделал это с pyserial.Чтение из одного потока и запись из другого не должно вызывать проблем в целом, так как в действительности нет проблем с арбитражем ресурсов.Последовательные порты являются полнодуплексными, поэтому чтение и запись могут происходить совершенно независимо и одновременно.

4 голосов
/ 11 января 2012

Я использовал pyserial таким образом в Linux (и Windows), без проблем!

0 голосов
/ 08 февраля 2014

Я написал скрипт, который делает это. Смотри: https://code.google.com/p/rpicopter/source/browse/RPiQuadroServer.py

0 голосов
/ 02 февраля 2013

Я бы рекомендовал изменить поток B с «блокирующего чтения» на «не блокирующего чтения / записи».Поток B станет вашим последовательным портом "Daemon".

Поток A может работать на полной скорости для дружественного пользовательского интерфейса или выполнять любые операции в реальном времени.

Поток A будет писать сообщение в потокB вместо того, чтобы пытаться записать напрямую в последовательный порт.Если размер / частота сообщений мала, будет работать простой общий буфер для самого сообщения и флаг, указывающий, что присутствует новое сообщение.Если вам нужна более высокая производительность, вы должны использовать стек.На самом деле это реализуется просто с помощью массива, достаточно большого, чтобы накапливать много отправляемых сообщений, и двух указателей.Указатель записи обновляется только потоком A. Указатель чтения обновляется только потоком B.

Поток B может получить сообщение и отправить его на последовательный порт.Последовательный порт должен использовать функцию тайм-аута, чтобы функция чтения последовательного порта освобождала ЦП, позволяя вам опросить общий буфер и, если появилось какое-либо новое сообщение, отправить его на последовательный порт.В этот момент я бы использовал режим сна, чтобы ограничить время процессора, используемое потоком B. Затем вы можете сделать цикл потока B функцией чтения последовательного порта.Если тайм-аут последовательного порта не работает должным образом, например, если кабель USB-RS232 отключен, функция сна будет отличать хороший код Python от плохого.

...