Russian Qt Forum
Сентябрь 30, 2024, 06:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSerial and QThread  (Прочитано 5394 раз)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« : Март 23, 2016, 12:15 »

Скажите можно ли читать с порта в отдельном потоке без использования сигнала
Код:
readyRead()
Ведь если мы используем сигналы, то получается надо будет использовать в потоке
Код:
exec()
т.е обработку очереди сообщений так???

А читать типа:
Код
C++ (Qt)
void Thread::run(){
for(;;){
  ...
  QByteArray ba = port->readAll();
 ...
}
}
 

Или это не правильно???

Записан
Vamireh
Гость
« Ответ #1 : Март 23, 2016, 12:33 »

В c#, boost и winapi так и делаю. QSerial почему-то падает в таком случае, особо не разбирался почему. Со стеком что-то.
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #2 : Март 23, 2016, 14:26 »

Или реализовать примерно так
Создаем объект порта типа основном потоке. Как глобальную переменную;
Создаем отдельно объект потока на чтение и запись и соответственно передаем в них указатель на объект порта.
Код
C++ (Qt)
 
extern Port port;
 
void MainWindow::MainWindow(QWidget*parent){
 
     thread_tx = new Thread_Tx(&port,0);
     ...
     thread_rx = new Thread_Rx(&port,0);
     ...
}
 

Код
C++ (Qt)
class Port: public QObject
{
Q_OBJECT
public:
...
 
private:
QSerialPort *serialPort;
 
}
 

Код
C++ (Qt)
void Thread_Tx::Thread_Tx(Port *thread_port,QObject*parent = 0){
my_port = thread_port;
...
}
 
void Thread_Tx::run(){
forever(){
 if(!start){
   break;
 }
 ...
 mutex_port.lock();
 bufferTx = my_port->read();
 mutex_port.unlock();
}//forever end
}
 

Код
C++ (Qt)
void Thread_Rx::Thread_Rx(Port *thread_port,QObject*parent = 0){
my_port = thread_port;
...
}
 
 
void Thread_Rx::run(){
forever(){
 if(!start){
   break;
 }
 ...
 mutex_port.lock();
 bufferRx = my_port->write();
 mutex_port.unlock();
}//forever end
}
 

 Непонимающий Непонимающий Непонимающий
« Последнее редактирование: Март 23, 2016, 14:42 от demaker » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Март 23, 2016, 15:33 »

Нет, нельзя.
Записан

ArchLinux x86_64 / Win10 64 bit
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #4 : Март 23, 2016, 17:37 »

Почему???
Т.е нельзя в одном потоке считывать и с другого
писать??? И как тогда делать???
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Март 23, 2016, 17:59 »

сигналы/слоты

PS: То же относится и к Qt-шным сокетам, пайпам, процессам и пр.
Записан

ArchLinux x86_64 / Win10 64 bit
Bepec
Гость
« Ответ #6 : Март 23, 2016, 18:12 »

Qt это комплекс. Нельзя из него выдрать лишь часть, не выдирая основных систем.
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #7 : Март 23, 2016, 18:15 »

Непонимающий Не понимаю Вас
Я же не выдергиваю ничего, а просто не использую)
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #8 : Март 23, 2016, 18:17 »

Не использую сигналы и слоты
Записан
Bepec
Гость
« Ответ #9 : Март 23, 2016, 18:41 »

Угу. А 90% классов Qt нуждаются в ней. Вот и нестыковочка...

Сигнал слоты решают много задач, от синхронизации потоков, до передачи структур данных, а вы их просто не используете Улыбающийся И если хоть в одном месте сигнал слоты были использованы, вы получите фигу, что на мой взгляд и происходит Улыбающийся
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #10 : Март 23, 2016, 19:45 »

Ведь если мы используем сигналы, то получается надо будет использовать в потоке
Код:
exec()
т.е обработку очереди сообщений так???
так.
А читать типа:
Код
C++ (Qt)
void Thread::run(){
for(;;){
...
QByteArray ba = port->readAll();
...
}
}
 
Или это не правильно???
Неправильно. port у вас создан в другом потоке, и использовать в run его не имеете права:
Цитировать
Note: The serial port is always opened with exclusive access (that is, no other process or thread can access an already opened serial port).
Так что либо создавайте порт в run (без привязки объекта к предку this), либо создавайте какой-нибудь объект в run, а его слот соединяйте с readyread. Полученные данные можно передать сигналом куда угодно.
И помните правила:
1) слот должен быть объявлен в объекте, который создается в том потоке, куда вы хотите передать данные. Сигнал может испускаться откуда угодно;
2) когда создаете объект в методе QThread::run, не указывайте для него предка this. Сам объект QTread создается в другом (чаще всего, в основном) потоке;
3) там, где находится слот, должна быть запущена обработка событий (exec).




Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #11 : Март 24, 2016, 11:02 »

Ок, я понял Вас.
Т.е QSerial не thread_save.
И с QSerial надо работать только в одном потоке.
Спасибо!!!  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.41 секунд. Запросов: 23.