QThread, bad file descriptor
I created an instance of RS class inside MainWindow. when fd is opened, it gives the value of 19 inside debugger. But, when I access it from inside of the Thread, it always gives value 0.
this is my main file: it initializes a thread that regularly generates packets inside queue as producer, and consumer on the other end, writes them to serial.
serial port is opened in Mainwindow constructor:
Code:
rs_plc.rs_plcOpenPort((char *)"/dev/ttyS0"); /*/dev/ttyS3*/
Code:
ThreadSafeQueue<QByteArray> UpdateJackQueue;
PlcUpdateThread *plcUpdateProd = new PlcUpdateThread(UpdateJackQueue, 1);
plcUpdateProd->start();
PlcUpdateThread *plcUpdateCons = new PlcUpdateThread(UpdateJackQueue, 0);
plcUpdateCons->start();
here is the Thread:
Code:
#ifndef PLCUPDATETHREAD_H
#define PLCUPDATETHREAD_H
#include <QByteArray>
#include <QThread>
#include "threadsafequeue.h"
#include "safilanLib.h"
#include "rs485.h"
#include <QDebug>
class PlcUpdateThread
: public QThread{
Q_OBJECT
public:
PlcUpdateThread(ThreadSafeQueue<QByteArray> &q, bool isProducer) : _queue(q), _prod(isProducer) {
if(_prod)
qDebug() << "I am a producer";
else
qDebug() << "I am a consumer";
}
void run() {
if(_prod)
while(1) produce();
else
while(1) consume();
}
void produce() {
const char str[]={UPDATE_xx};
_queue.enqueue(built);
// qDebug() << _queue.count();
msleep(100);
//sleep(qrand()%5);
}
void consume() {
qDebug() << "cosume";
qDebug() << v.toHex();
rs_plc.writeToSerialPort(v);
qDebug() << _queue.count();
msleep(300);
// sleep(qrand()%5);
}
public slots:
private:
ThreadSafeQueue<QByteArray> &_queue;
bool _prod;
};
#endif // PLCUPDATETHREAD_H
here is the write to serial function that the above thread calls:
and here is the RS instance created statically write after the RS class:
Code:
void rs_flushPort ();
bool rs_plcConfigPort();
bool rs_azmthConfigPort();
};
static RS rs_plc;
Re: QThread, bad file descriptor
Please provide a minimal compilable example reproducing the problem.
Re: QThread, bad file descriptor
Quote:
Originally Posted by
wysota
Please provide a minimal compilable example reproducing the problem.
can't be more minimized than above now. I omitted serial write, forget about it.
When fd is set in RS class instance, when I access serial class member from thread, fd is 0. However, If I open and close serial port inside thread everytime I write then it writes successfully! should I keep that way?
this way it works fine:
Code:
void consume() {
qDebug() << "cosume";
qDebug() << v.toHex();
rs_plc.rs_plcOpenPort((char *)"/dev/ttyS0");
rs_plc.writeToSerialPort(v);
qDebug() << _queue.count();
msleep(300);
// sleep(qrand()%5);
}
moreover, the other problem is with reading. inside another thread, I read serial by producer and update ui by consumer, but producer never reads from serial, even when I send a packet via DB9 ,it does not catch it. here is the reading and updating ui thread:
Code:
void produce() {
qDebug() << "produce";
if(rs_plc.rs_plcRead(&rd15Bytes))
{
if(!rd15Bytes.isEmpty())
{
// qDebug() << "Enqueue";
_queue.enqueue(rd15Bytes);
}
}
msleep(100);
}
void consume() {
qDebug() << "cosume";
rs_plc.updateUI(v);
msleep(200);
}
you may not worry about read and write functions to serial, as they are properly checked and work fine without using threads.
Re: QThread, bad file descriptor
Quote:
Originally Posted by
saman_artorious
can't be more minimized than above now.
But it can be more compilable than now.
Re: QThread, bad file descriptor
let me think how to tell you what I really want to do.
Re: QThread, bad file descriptor
thanks for the producer consumer problem you referenced. i tried it. I use two instances of this class, in the first, producer writes packets to queue, consumer dequeues and writes them to serial. (So, two threads). in the next two threads, producer reads from serial constantly and enqueues buffer, the consumer then dequeues and updates UI.
I have the following problems:
1. in this class queue is defined privately inside threadsafequeue, this causes some problems, other objects cannot enqueue inside the queue if it is private! I have defined the threads in main.cpp. but how can other object tell it that they want these packets enQd into queue. so that the consumer can write them to serial? on the other hand if I define the queue not inside of the class and instead in a global header, I receive multiple definition of variable error.
2.Let's consider four threads, the RS class that communicates with serial and other objects that enqueue packets to queue to be written to serial. The write to serial in producer works fine. but the consumer can never read from serial, always returns length 0 or rarely length that is less than expected. Moreover, in this class I cannot pass packets to thread, otherwise, other object coudav used thread instance to enquque packets into its Q.
3. I used emit in a single thread, it works fine, but in the producer consumer class emit are not active. when I receive the packet from serial inside of RS class, I emit it to UI. but it doesn't work!
I do not know how to correct the structure of my program. please help me. I added the code above to clarify what is happening in my code.
please ask me for further info, i am very curious to solve the structure of my program with threads.
thanks for the producer consumer problem you referenced. i tried it. I use two instances of this class, in the first, producer writes packets to queue, consumer dequeues and writes them to serial. (So, two threads). in the next two threads, producer reads from serial constantly and enqueues buffer, the consumer then dequeues and updates UI.
I have the following problems:
1. in this class queue is defined privately inside threadsafequeue, this causes some problems, other objects cannot enqueue inside the queue if it is private! I have defined the threads in main.cpp. but how can other object tell it that they want these packets enQd into queue. so that the consumer can write them to serial? on the other hand if I define the queue not inside of the class and instead in a global header, I receive multiple definition of variable error.
2.Let's consider four threads, the RS class that communicates with serial and other objects that enqueue packets to queue to be written to serial. The write to serial in producer works fine. but the consumer can never read from serial, always returns length 0 or rarely length that is less than expected. Moreover, in this class I cannot pass packets to thread, otherwise, other object coudav used thread instance to enquque packets into its Q.
3. I used emit in a single thread, it works fine, but in the producer consumer class emit are not active. when I receive the packet from serial inside of RS class, I emit it to UI. but it doesn't work!
I do not know how to correct the structure of my program. please help me. I added the code above to clarify what is happening in my code.
please ask me for further info, i am very curious to solve the structure of my program with threads.
Re: QThread, bad file descriptor
First of all I don't understand why you are using threads at all here if they are causing you problems. Implement your program in a single thread instead.
Re: QThread, bad file descriptor
I did but it slows down the UI. because when timers trigger, they write and read from serial. So, meanwhile entering input in the UI will not be fast. The write n read to the serial is in the way that when I write, I delay() a bit followed by the read. Then I emit the read packet to UI. This is why decided to use Thread to handle write n read to serial in another thread so that UI does not have to wait for serial write n reads.
What should I do ?
Re: QThread, bad file descriptor
Quote:
Originally Posted by
saman_artorious
I did but it slows down the UI.
If it does then apparently you have not done it correctly.
Re: QThread, bad file descriptor
and about the bad file descriptor. say, I have a serial class:
Code:
class RS
{
}
static RS var
I open this port in mainwindow, but when I access its member function from inside of a thread using the static variable
Code:
::run()
{
staticvariable.sendToserial(param);
msleep(300);
}
it gives bad file descriptor. it seems that the variable fd defined inside serial class gets lost!
I also replaced opening port from mainwindow to serial class constructor, this way when program runs, it opens port many times!
any ideas?
Re: QThread, bad file descriptor
The best idea is to use ready classes wrappers for work with serial ports in Qt. For example QtSerialPort (preferred) or QextSerialPort.
It much quicker and more conveniently, than you will fool about with threads, etc., IMHO.
Re: QThread, bad file descriptor
Quote:
Originally Posted by
saman_artorious
and about the bad file descriptor. say, I have a serial class:
Code:
class RS
{
}
static RS var
I open this port in mainwindow, but when I access its member function from inside of a thread using the static variable
Code:
::run()
{
staticvariable.sendToserial(param);
msleep(300);
}
it gives bad file descriptor. it seems that the variable fd defined inside serial class gets lost!
I also replaced opening port from mainwindow to serial class constructor, this way when program runs, it opens port many times!
any ideas?
I have no idea what your code as doing and since you're not willing to show your code but instead all you do is provide random snippets that do not demonstrate the problem, there is nothing I (and possibly all the other participants) can do for you.
Re: QThread, bad file descriptor
Ok, Consider this thread, it acts like a timer, send some packet to serial:
Code:
void PlCThead::run()
{
while(1)
{
const char str[]={UPDATE_PACKET};
emit requestForWriteAndReceive((char* )str, 3);
msleep(100);
}
}
emit works fine, it goes inside the slot, there, it writes only 78 or char x to serial instead of a packet of 3 bytes.
Code:
bool RS::rs_serialWrite(char* buff, size_t length)
{
int variables....;
qDebug() << built.toHex(); //this is correct, a packet of size 3
len = write(fd, buff, length);
qDebug() << len; //this returns 3! but it only write x to serial
qDebug() << strerror(errno);
return true;
}
strerror returns back this warning:
Quote:
Resource temporarily unavailable
any ideas? this code works fine with timers, it has been checked and tested accurately, but now i need to add this thread instead of the timer. Thanks (;))
Re: QThread, bad file descriptor
As I already said about a week ago, your code in run() is invalid. You are emitting a pointer to a local variable which you'll likely overwrite with other data before anyone has a chance to use the pointer. Emit a byte array instead or use some other data structure to share data between threads. Or drop threads, you really have no need for them.
Re: QThread, bad file descriptor
i cannot attach files here, I will attach it in a new post.