Search code examples
linuxmultithreadingqtposixpppd

Keeping main thread (Qt Application) responsive while some other thread is processing (POSIX)


System / software Details : Qt Version 4.7.4

Linux Kernel : 2.6.31 (Custom kernel built for IMX25)

Peripherals : Graphic LCD (64x128) Quectel (M 12) GPRS module Thermal printer

Database : Sqlite3

I am a beginner don't have much experience either in Qt or programming with Linux. I have developed an application where user enter some data manually and that data gets saved in sqlite database. So what I am trying to do is that after certain time lets say 90 seconds data from database should get transferred to the server using the GPRS.

So I am using the Qt's signal and slots mechanism to do the timed data transfer. I have created a slot which gets fired every 90 seconds and as the slot gets fired I am creating/launching a POSIX thread which is suppose to transfer the data to the server.

So what that thread does is it launches the "pppd" and once the "pppd" is up it queries the database for the data and sends the data to the server. And once the data transfer is done I kill the "pppd". The functionality works fine.

But the problem is that the "pppd" takes time to launch so I had to introduce some delay. i.e sleep of 12 seconds is there in order to let the pppd launch successfully. But as the sleep is blocking it makes the main program/thread non responsive until the "pppd" is launched (i.e. it halts/stops all the activities like printing etc.). And as the "pppd" is launched the main thread becomes responsive again.

So please suggest me some solution in order to keep the main thread responsive when "pppd" is launching or please suggest me if there is any other alternative for the same. Also guide me if there's anything wrong with my approach..

Thanks in advance. And I am sorry if I have not followed your standards..


Solution

  • There are several options available to you. It looks like you're using a thread, but then calling sleep in the main thread, which is basically the same as not using thread to do your work at all! You need to leverage Qt processes as illustrated below:

    You can use a QProcess in which you start() and use the signal finished() to notify the main thread that it is complete. This is probably what you want to use. All you have to do is:

    QProcess *proc = new QProcess;
    proc->start("theProcess", QStringList() << "the" << "arguments");
    connect(proc, SIGNAL(finished()), this, SLOT(someSlotToUse()));
    

    This sequence of code will start a new process with your arguments, and then call someSlotToUse() when the process is complete.

    You can use a QThread along the same pattern.

    Basically, what you're trying to do is do the work in another thread, keeping the GUI reactor free to process GUI events rather than long queries. This is a classic problem in Qt and there is a lot of literature out there.

    Alternately, you can use a QProcess::concurrent() call, which allows you to run a function in another process, but I've never tested it.

    Here are some references for you to look at: Qt Concurrent, QProcess, and QThread