Russian Qt Forum

Qt => Вопросы новичков => Тема начата: demaker от Март 23, 2016, 12:15



Название: QSerial and QThread
Отправлено: demaker от Март 23, 2016, 12:15
Скажите можно ли читать с порта в отдельном потоке без использования сигнала
Код:
readyRead()
Ведь если мы используем сигналы, то получается надо будет использовать в потоке
Код:
exec()
т.е обработку очереди сообщений так???

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

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



Название: Re: QSerial and QThread
Отправлено: Vamireh от Март 23, 2016, 12:33
В c#, boost и winapi так и делаю. QSerial почему-то падает в таком случае, особо не разбирался почему. Со стеком что-то.


Название: Re: QSerial and QThread
Отправлено: demaker от Март 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
}
 

 ??? ??? ???


Название: Re: QSerial and QThread
Отправлено: kuzulis от Март 23, 2016, 15:33
Нет, нельзя.


Название: Re: QSerial and QThread
Отправлено: demaker от Март 23, 2016, 17:37
Почему???
Т.е нельзя в одном потоке считывать и с другого
писать??? И как тогда делать???


Название: Re: QSerial and QThread
Отправлено: kuzulis от Март 23, 2016, 17:59
сигналы/слоты

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


Название: Re: QSerial and QThread
Отправлено: Bepec от Март 23, 2016, 18:12
Qt это комплекс. Нельзя из него выдрать лишь часть, не выдирая основных систем.


Название: Re: QSerial and QThread
Отправлено: demaker от Март 23, 2016, 18:15
??? Не понимаю Вас
Я же не выдергиваю ничего, а просто не использую)


Название: Re: QSerial and QThread
Отправлено: demaker от Март 23, 2016, 18:17
Не использую сигналы и слоты


Название: Re: QSerial and QThread
Отправлено: Bepec от Март 23, 2016, 18:41
Угу. А 90% классов Qt нуждаются в ней. Вот и нестыковочка...

Сигнал слоты решают много задач, от синхронизации потоков, до передачи структур данных, а вы их просто не используете :) И если хоть в одном месте сигнал слоты были использованы, вы получите фигу, что на мой взгляд и происходит :)


Название: Re: QSerial and QThread
Отправлено: sergek от Март 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).






Название: Re: QSerial and QThread
Отправлено: demaker от Март 24, 2016, 11:02
Ок, я понял Вас.
Т.е QSerial не thread_save.
И с QSerial надо работать только в одном потоке.
Спасибо!!!  :)