0

The java version works exactly as expected while the C++ version crashes. The C++ version somehow does work when 1 <= N_THREADS <= 2 but otherwise it fails.

I've struggled for hours trying to make the C++ version work but failed and still have no idea what is going on. For sure I will know the problem by studying system threads and the Qthread source code, and yes I will try to do that, but I also do need a solution now.

Any help appreciated.

thread_test.java

class my_thread extends Thread
{
    int n;

    my_thread()
    {
        n = 0;
    }

    public void run()
    {
        try
        {
            while (n < 10)
            {
                System.out.print(n++);
                Thread.sleep(1000);
            }
        }
        catch (InterruptedException e)
        {
            return;
        }
    }
}

public class thread_test
{
    public static void main(String[] args)
    {
        final int N_THREADS = 10;
        for (int i = 0; i < N_THREADS; i++)
        {
            new my_thread().start();
        }
    }
}

thread_test.cpp

#include <array>
#include <QTextStream>
#include <QThread>

QTextStream qout(stdout);

class my_thread : public QThread
{
public:
    int n;

    my_thread()
    {
        n = 0;
    }

    void run()
    {
        while(n < 10)
        {
            qout << n++ << flush;
            msleep(1000);
        }
    }
};

int main()
{
    enum { N_THREADS = 10 };
    std::array<my_thread, N_THREADS> thread_array;
    for (auto& thread : thread_array)
    {
        thread.start();
    }
    for (auto& thread : thread_array)
    {
        thread.wait();
    }
    return 0;
}

EDIT

Reading the comments and with some Google search, the problem in my C++ code definitely seems to be using non-threadsafe operations in multiple threads. So here my problem will be solved by making QTextStream threadsafe just as Java's PrintStream.

Based on my quick web search I kind of guess that the process where QTextStream is interacting with the standard output shouldn't be done through multiple threads at the same time since there is only one standard output. But it would be too slow to make all other threads wait during one thread is interacting with the standard output. So I think the right solution would be making a queue to store the output to be written, as QString references, while stdout is busy and cannot accept more task at the same time. Well, then here how do I guarantee that this queue is thread safe? I am very confused right now. Also, how is Java PrintStream implemented as threadsafe? Please help me organizing these issues and finding the right solution to this problem.

  • 1
    The only thing I can think of right now: Are you sure that QTextStream is threadsafe? Does it work if you leave out the `qout` line or replace it with qDebug()? – anderas Nov 18 '14 at 08:56
  • 2
    *otherwise it fails* does not give us any idea of whats really happens – ortis Nov 18 '14 at 08:56
  • @ortis Sometimes the program simply stops operating, in most times it prints about twice as long output than it should, with a lot of unexpected spaces in between the numbers... –  Nov 18 '14 at 08:58
  • 3
    `QTextStream` is not thread-safe! – Ezee Nov 18 '14 at 09:02
  • @anderas `qDebug()` doesn't work also. What exactly is being threadsafe? or how can I make QTextStream threadsafe if it is not and thus is causing the problem? –  Nov 18 '14 at 09:03
  • 1
    The Qt docs say if the class is thread safe or not. In case of [`QTextStream`](http://qt-project.org/doc/qt-5/qtextstream.html) it says `Note: All functions in this class are reentrant.`. And you can read about the difference between reentrancy and thread safety [here](http://qt-project.org/doc/qt-5/threads-reentrancy.html#reentrant). – thuga Nov 18 '14 at 09:06

1 Answers1

0

In Qt you are not supposed to derive QThread because you want functionality run in a thread and not the thread having that functionality.

Just have a look at those links, the first discribes the threading more general, the second helps implementing.

https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

what is the correct way to implement a QThread... (example please...)

ZygD
  • 22,092
  • 39
  • 79
  • 102
Zaiborg
  • 2,492
  • 19
  • 28