Why this thread prints out nothing



  • This is trivial code yet it doesn't function as expected. Why this code prints out nothing.

    #include <QCoreApplication>
    #include <QDebug>
    #include <QThread>
    
    
    class TextThread : public QThread
    {
    public:
    	TextThread(const QString &text);
    	void run();
    private:
    	QString m_text;
    };
    
    bool stopThreads = false;
    TextThread::TextThread(const QString &text) : QThread()
    {
    	m_text = text;
    }
    
    void TextThread::run()
    {
    	while(!stopThreads){
    		qDebug() << m_text;
    		sleep(1);
    	}
    }
    
    int main(int argc, char *argv[])
    {
    	
    	QCoreApplication app(argc, argv);
    	
    	TextThread foo("Foo"), bar("Bar");
    	foo.start();
    	bar.start();
    	stopThreads = true;
    	foo.wait();
    	bar.wait();
    	
    	return app.exec();
    }
    


  • @CroCo hi,friend,welcome.

    maybe your thread had not to run when you to set stopThreads = true. you can try it by below code snippet.

    int main(int argc, char *argv[])
    {
    
        QCoreApplication app(argc, argv);
    
        TextThread foo("Foo"), bar("Bar");
    
        foo.start();
        bar.start();
    
        qDebug() << foo.isRunning() << ":" << bar.isRunning();
        QThread::sleep(3); //< let the main thread sleep some seconds
        qDebug() << foo.isRunning() << ":" << bar.isRunning();
    
        stopThreads = true;
    
        foo.wait();
        bar.wait();
    
        return app.exec();
    }
    


  • Our good old friend: the race condition.

    1. bool stopThreads should become std::atomic_bool stopThreads
    2. no need to use QThread if you don't require signal/slot communication, just use
    std::async([&stopThreads]()->void{while(!stopThreads){
    		qDebug() << m_text;
    		sleep(1);
    	}});
    
    1. If you really want to learn the correct way of using QThread, see https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
    #include <QApplication>
    #include <thread>
    #include <future>
    #include <chrono>
    #include <iostream>
    #include <atomic>
    int main(int argc, char *argv[])
    {
    QCoreApplication app(argc, argv);
    std::atomic_bool stopThreads;
    stopThreads=false;
    const auto printEverySecond = [&stopThreads](const QString& text)->void{
    while(!stopThreads){
    std::cerr<< qPrintable(text);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    };
    std::async(std::launch::async,printEverySecond,QStringLiteral("Foo"));
    std::async(std::launch::async,printEverySecond,QStringLiteral("Bar"));
    std::async(std::launch::async,[&stopThreads]()->void{ std::this_thread::sleep_for(std::chrono::seconds(5)); stopThreads=true;});
    return app.exec();
    }
    


  • @VRonin
    How does your use of std::async([&stopThreads]()) ultimately avoid the issue of precisely when the main program chooses to set stopThreads = true versus how long/many times the thread is allowed to print out m_text?



  • @JNBarchan Yep, that's why I added the full example in an edit. Also, must be noted, I don't think qDebug() is thread safe so I switched to good old std::cerr



  • @VRonin
    Yep, we crossed :)


  • Moderators

    @VRonin said in Why this thread prints out nothing:

    I don't think qDebug() is thread safe so I switched to good old std::cerr

    This was discussed in the Development mailing list recently, but it seems to be missing from the archives. The discussion led to https://codereview.qt-project.org/#/c/208249/

    Basically, qDebug is thread safe, but stderr is unbuffered. Therefore, when 2 threads write long messages to qDebug at the same time, the output from the threads could become interleaved. However, if we install a custom message handler and make qDebug write to stdout instead of stderr, the problem disappears.


  • Qt Champions 2017

    @VRonin said in Why this thread prints out nothing:

    I don't think qDebug() is thread safe so I switched to good old std::cerr

    It is and has been for ages, it's just not reflected in the docs (as @JKSH pointed out). It's intended for debug only, though, not for application logging.



  • @VRonin said in Why this thread prints out nothing:

    atomic_bool

    using atomic_bool didn't solve the problem.



  • @joeQ not sure but this is a sample borrowed from a book about Qt.


  • Qt Champions 2017

    1. Where are you looking for the debug output?
    2. does it print from the main thread? (I imagine no)


  • @kshegunov from the command prompt. No it doesn't print from the main thread.



  • @CroCo
    I'm interested in this, but lost as to just what your code now looks like? Is it exactly (more or less) as per your original post still, or have you done stuff as per either @joeQ or @VRonin 's code?

    In particular, if you sleep after you have started your threads and before you set stopThreads = true, you really should see output from threads' run()?

    And to eliminate any arguments about qDebug/output, if you run under debugger and place breakpoint in TextThread::run, what do you actually hit/not hit? (If you really can't use a debugger, at least put in a qDebug() << "Got here"; as the first statement in TextThread::run, so we're not wondering about stopThreads value.) Even though your code is "simple", at this point given that you haven't found an answer there is still quite a bit of possible simplification to reduce the issue to its nub.


  • Moderators

    @CroCo said in Why this thread prints out nothing:

    @kshegunov from the command prompt. No it doesn't print from the main thread.

    Are you using Windows? Your debug output might be going to the system debug log instead of the command prompt. You can monitor the system debug log by running DebugView before you start your app: https://docs.microsoft.com/en-us/sysinternals/downloads/debugview

    If you still can't see your debug messages,

    1. Post your *.pro file
    2. Post your latest code
    3. Tell us: How are you building your app, and how are you running your app?

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.