0

Three threads are created that instantiate the same class.
Each thread has a different delay. But after some time only 1 thread executes. ???

GenNum1 = new CGenerateNumbers();
GenNum1->m_threadNumber = 1;
GenNum1->m_usec = 10000;
connect(GenNum1, SIGNAL(OnIndexReady()), this, SLOT(hGenNumOnIndexReady1()));

QThread *tGenNum1 = new QThread;
GenNum1->moveToThread(tGenNum1);
GenNum1->connect(tGenNum1, SIGNAL(started()), GenNum1, SLOT(Started()), Qt::DirectConnection);
tGenNum1->start();




GenNum2 = new CGenerateNumbers();
GenNum2->m_threadNumber = 2;
GenNum2->m_usec = 15000;
connect(GenNum2, SIGNAL(OnIndexReady()), this, SLOT(hGenNumOnIndexReady2()));

QThread *tGenNum2 = new QThread;
GenNum2->moveToThread(tGenNum2);
GenNum2->connect(tGenNum2, SIGNAL(started()), GenNum2, SLOT(Started()), Qt::DirectConnection);
tGenNum2->start();




GenNum3 = new CGenerateNumbers();
GenNum3->m_threadNumber = 3;
GenNum3->m_usec = 20000;
connect(GenNum3, SIGNAL(OnIndexReady()), this, SLOT(hGenNumOnIndexReady3()));

QThread *tGenNum3 = new QThread;
GenNum3->moveToThread(tGenNum3);
GenNum3->connect(tGenNum3, SIGNAL(started()), GenNum3, SLOT(Started()), Qt::DirectConnection);
tGenNum3->start();

//this is what each thread calls to:
void CGenerateNumbers::Started()
{
    int i = 0;
    int c = 0;
    char v;

    while(1){
        usleep(m_usec);

        v = (i % 26) + 65;

        for(int j = 0; j < 11; j++){
            mem->m_cmMessageWrite.cMessage[j] = v;
        }
        mem->m_cmMessageWrite.cMessage[0] = m_threadNumber + 48;
        mem->m_cmMessageWrite.cMessage[1] = 32;

        mem->Write();

        m_i = i;

        emit OnIndexReady();
        i++;
    }
}

index  index   thread  message

0       0       1 AAAAAAAAA
1       1       2 AAAAAAAAA
2       2       3 AAAAAAAAA
3       3       1 BBBBBBBBB
4       4       1 CCCCCCCCC
5       5       2 BBBBBBBBB
6       6       3 BBBBBBBBB
7       7       1 DDDDDDDDD
8       8       2 CCCCCCCCC
9       9       1 EEEEEEEEE
10      10      3 CCCCCCCCC
11      11      1 FFFFFFFFF
12      12      2 DDDDDDDDD
13      13      1 GGGGGGGGG
14      14      2 EEEEEEEEE
15      15      3 DDDDDDDDD
16      16      1 HHHHHHHHH
17      17      1 IIIIIIIII
18      18      2 FFFFFFFFF
19      19      3 EEEEEEEEE
20      20      1 JJJJJJJJJ
21      21      2 GGGGGGGGG
22      22      1 KKKKKKKKK
23      23      3 FFFFFFFFF
24      24      2 HHHHHHHHH
25      25      1 LLLLLLLLL
26      26      2 IIIIIIIII
27      27      3 GGGGGGGGG
28      28      1 MMMMMMMMM
29      29      1 NNNNNNNNN
30      30      2 JJJJJJJJJ
31      31      3 HHHHHHHHH
32      32      1 OOOOOOOOO
33      33      2 KKKKKKKKK
34      34      1 PPPPPPPPP
35      35      3 IIIIIIIII
36      36      1 QQQQQQQQQ
37      37      2 LLLLLLLLL
38      38      1 RRRRRRRRR
39      39      2 MMMMMMMMM
40      40      1 SSSSSSSSS
41      41      2 NNNNNNNNN
42      42      1 TTTTTTTTT
43      43      1 UUUUUUUUU
44      44      1 VVVVVVVVV
45      45      1 WWWWWWWWW
46      46      2 OOOOOOOOO
47      47      1 XXXXXXXXX
48      48      2 PPPPPPPPP
49      49      1 YYYYYYYYY
50      50      2 QQQQQQQQQ
51      51      1 ZZZZZZZZZ
52      52      1 AAAAAAAAA
53      53      2 RRRRRRRRR
54      54      1 BBBBBBBBB
55      55      2 SSSSSSSSS
56      56      1 CCCCCCCCC
57      57      1 DDDDDDDDD
58      58      2 TTTTTTTTT
59      59      1 EEEEEEEEE
60      60      2 UUUUUUUUU
61      61      1 FFFFFFFFF
62      62      1 GGGGGGGGG
63      63      2 VVVVVVVVV
64      64      1 HHHHHHHHH
65      65      2 WWWWWWWWW
66      66      1 IIIIIIIII
67      67      1 JJJJJJJJJ
68      68      2 XXXXXXXXX
69      69      1 KKKKKKKKK
70      70      2 YYYYYYYYY
71      71      1 LLLLLLLLL
72      72      1 MMMMMMMMM
73      73      2 ZZZZZZZZZ
74      74      1 NNNNNNNNN
75      75      2 AAAAAAAAA
76      76      1 OOOOOOOOO
77      77      1 PPPPPPPPP
78      78      2 BBBBBBBBB
79      79      1 QQQQQQQQQ
80      80      2 CCCCCCCCC
81      81      1 RRRRRRRRR
82      82      1 SSSSSSSSS
83      83      2 DDDDDDDDD
84      84      1 TTTTTTTTT
85      85      2 EEEEEEEEE
86      86      1 UUUUUUUUU
87      87      1 VVVVVVVVV
88      88      2 FFFFFFFFF
89      89      1 WWWWWWWWW
90      90      2 GGGGGGGGG
91      91      1 XXXXXXXXX
92      92      1 YYYYYYYYY
93      93      2 HHHHHHHHH
94      94      1 ZZZZZZZZZ
95      95      2 IIIIIIIII
96      96      1 AAAAAAAAA
97      97      1 BBBBBBBBB
98      98      2 JJJJJJJJJ
99      99      1 CCCCCCCCC
100     100     2 KKKKKKKKK
101     101     1 DDDDDDDDD
102     102     2 LLLLLLLLL
103     103     1 EEEEEEEEE
104     104     2 MMMMMMMMM
105     105     1 FFFFFFFFF
106     106     1 GGGGGGGGG
107     107     2 NNNNNNNNN
108     108     1 HHHHHHHHH
109     109     2 OOOOOOOOO
110     110     1 IIIIIIIII
111     111     1 JJJJJJJJJ
112     112     2 PPPPPPPPP
113     113     1 KKKKKKKKK
114     114     2 QQQQQQQQQ
115     115     1 LLLLLLLLL
116     116     1 MMMMMMMMM
117     117     2 RRRRRRRRR
118     118     1 NNNNNNNNN
119     119     2 SSSSSSSSS
120     120     1 OOOOOOOOO
121     121     1 PPPPPPPPP
122     122     2 TTTTTTTTT
123     123     1 QQQQQQQQQ
124     124     2 UUUUUUUUU
125     125     1 RRRRRRRRR
126     126     2 VVVVVVVVV
127     127     1 SSSSSSSSS
128     128     1 TTTTTTTTT
129     129     2 WWWWWWWWW
130     130     1 UUUUUUUUU
131     131     2 XXXXXXXXX
132     132     1 VVVVVVVVV
133     133     2 YYYYYYYYY
134     134     1 WWWWWWWWW
135     135     1 XXXXXXXXX
136     136     2 ZZZZZZZZZ
137     137     1 YYYYYYYYY
138     138     2 AAAAAAAAA
139     139     1 ZZZZZZZZZ
140     140     1 AAAAAAAAA
141     141     2 BBBBBBBBB
142     142     1 BBBBBBBBB
143     143     2 CCCCCCCCC
144     144     1 CCCCCCCCC
145     145     1 DDDDDDDDD
146     146     2 DDDDDDDDD
147     147     1 EEEEEEEEE
148     148     2 EEEEEEEEE
149     149     1 FFFFFFFFF
150     150     1 GGGGGGGGG
151     151     2 FFFFFFFFF
152     152     1 HHHHHHHHH
153     153     2 GGGGGGGGG
154     154     1 IIIIIIIII
155     155     2 HHHHHHHHH
156     156     1 JJJJJJJJJ
157     157     1 KKKKKKKKK
158     158     2 IIIIIIIII
159     159     1 LLLLLLLLL
160     160     2 JJJJJJJJJ
161     161     1 MMMMMMMMM
162     162     1 NNNNNNNNN
163     163     2 KKKKKKKKK
164     164     1 OOOOOOOOO
165     165     2 LLLLLLLLL
166     166     1 PPPPPPPPP
167     167     1 QQQQQQQQQ
168     168     2 MMMMMMMMM
169     169     1 RRRRRRRRR
170     170     2 NNNNNNNNN
171     171     1 SSSSSSSSS
172     172     1 TTTTTTTTT
173     173     2 OOOOOOOOO
174     174     1 UUUUUUUUU
175     175     2 PPPPPPPPP
176     176     1 VVVVVVVVV
177     177     2 QQQQQQQQQ
178     178     1 WWWWWWWWW
179     179     1 XXXXXXXXX
180     180     2 RRRRRRRRR
181     181     1 YYYYYYYYY
182     182     2 SSSSSSSSS
183     183     1 ZZZZZZZZZ
184     184     1 AAAAAAAAA
185     185     2 TTTTTTTTT
186     186     1 BBBBBBBBB
187     187     2 UUUUUUUUU
188     188     1 CCCCCCCCC
189     189     1 DDDDDDDDD
190     190     2 VVVVVVVVV
191     191     2 WWWWWWWWW
192     192     1 EEEEEEEEE
193     193     1 FFFFFFFFF
194     194     2 XXXXXXXXX
195     195     1 GGGGGGGGG
196     196     2 YYYYYYYYY
197     197     1 HHHHHHHHH
198     198     2 ZZZZZZZZZ
199     199     1 IIIIIIIII
200     200     1 JJJJJJJJJ
201     201     2 AAAAAAAAA
202     202     1 KKKKKKKKK
203     203     2 BBBBBBBBB
204     204     1 LLLLLLLLL
205     205     1 MMMMMMMMM
206     206     2 CCCCCCCCC
207     207     1 NNNNNNNNN
208     208     2 DDDDDDDDD
209     209     1 OOOOOOOOO
210     210     2 EEEEEEEEE
211     211     2 FFFFFFFFF
212     212     1 PPPPPPPPP
213     213     1 QQQQQQQQQ
214     214     1 RRRRRRRRR
215     215     1 SSSSSSSSS
216     216     1 TTTTTTTTT
217     217     1 UUUUUUUUU
218     218     1 VVVVVVVVV
219     219     1 WWWWWWWWW
220     220     1 XXXXXXXXX
221     221     1 YYYYYYYYY
222     222     1 ZZZZZZZZZ
223     223     1 AAAAAAAAA
224     224     1 BBBBBBBBB
225     225     1 CCCCCCCCC
226     226     1 DDDDDDDDD
227     227     1 EEEEEEEEE
228     228     1 FFFFFFFFF
229     229     1 GGGGGGGGG
230     230     1 HHHHHHHHH
231     231     1 IIIIIIIII
232     232     1 JJJJJJJJJ
233     233     1 KKKKKKKKK
234     234     1 LLLLLLLLL
235     235     1 MMMMMMMMM
236     236     1 NNNNNNNNN
237     237     1 OOOOOOOOO
238     238     1 PPPPPPPPP
239     239     1 QQQQQQQQQ
240     240     1 RRRRRRRRR
241     241     1 SSSSSSSSS
242     242     1 TTTTTTTTT
243     243     1 UUUUUUUUU
jdl
  • 6,151
  • 19
  • 83
  • 132

2 Answers2

2

There are two issues:

  1. You do not want to tell connect to use a direct connection, just leave that off, the default will be properly chosen for you. In this case, the two QObjects that you connect between live in different threads. The QThread object lives in the current thread - it's not a thread, it's a controller. The CGenerateNumbers instance lives in the new thread. So you do not want a direct connection, it must be a queued connection!

    In my applications I'm using a custom build of Qt and I've done a global search-replace of QThread with QThreadController. The latter is a more descriptive and less misleading name. There is no Qt class that is really equivalent to a thread per se.

  2. The mem->Write(); call may be blocking. It would not cause a thread to "die", but merely to block. If it's a deadlock, as I presume it might well be, the thread is stopped forever (deadlocked). It's not dead, only appears to be.

The code below demonstrates a SSCCE that works fine on both Qt 5 and Qt 4. You'd need to reduce your code to a similarly simple example, my bet is that your problem is with code that is NOT shown. Perhaps in the process of reduction you'll figure it out.

# threads-18369174.pro
QT       += core
QT       -= gui
TARGET = threads-18369174
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp

.

// main.cpp
#include <QCoreApplication>
#include <QObjectList>
#include <QList>
#include <QThread>
#include <iostream>

const int cycleCount = 500; //!< number of cycles to run at, set to 0 to run forever
const int threadCount = 5; //!< number of threads to create

class Object : public QObject
{
    Q_OBJECT
    int m_threadNumber;
    int m_delayUs;
    volatile bool m_active;
public:
    explicit Object(int delayUs, int no) : m_threadNumber(no), m_delayUs(delayUs) {}
    Q_SIGNAL void indexReady(int);
    Q_SLOT void stop() { m_active = false; }
    Q_SLOT void start()
    {
        m_active = true;
        while (m_active) {
            usleep(m_delayUs);
            emit indexReady(m_threadNumber);
        }
    }
};

class Consumer : public QObject
{
    Q_OBJECT
    QList<Object*> m_objects;
    QList<QThread*> m_threads;
    int m_threadCount; //!< number of active threads in m_threads
    int m_count;
public:
    Consumer() : m_count(0) {}
    void addObject(Object * o) { m_objects << o; }
    void addThread(QThread * t) {
        m_threads << t;
        m_threadCount ++;
        connect(t, SIGNAL(finished()), SLOT(done()));
        connect(t, SIGNAL(terminated()), SLOT(done()));
    }
    Q_SLOT void ready(int n) {
        std::cout << "<" << m_count++ << ":" << n << ">" << std::endl;
        if (m_count == cycleCount) {
            foreach (Object * o, m_objects) o->stop();
            foreach (QThread * t, m_threads) t->wait();
        }
    }
    Q_SLOT void done() {
        QThread * t = qobject_cast<QThread*>(sender());
        int i = m_threads.indexOf(t);
        if (t) t->deleteLater();
        if (i>=0) {
            std::cout << "\nThread " << i << " is done." << std::endl;
            m_threadCount --;
        }
        if (! m_threadCount) qApp->quit();
    }
};

int main(int argc, char *argv[])
{
    Consumer c;
    QObjectList l;
    QCoreApplication a(argc, argv);
    std::cout << "Running under Qt version " << qVersion() << std::endl;
    for (int i = 0; i < threadCount; ++i) {
        Object * o = new Object(10000 + 5000*i, i+1);
        QThread * t = new QThread;
        c.addObject(o);
        c.addThread(t);
        o->moveToThread(t);
        o->connect(t, SIGNAL(started()), SLOT(start()));
        c.connect(o, SIGNAL(indexReady(int)), SLOT(ready(int)));
        t->start();
        t->exit();
        l << o;
    }
    return a.exec();
}

#include "main.moc"
Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
1

For a given time period, thread 1 produces the most messages as it has the smallest sleep.

If your message receiver reads messages at a slower rate than the sending rate, then above output is expected as there were most messages from thread 1 and least messages from thread 3 in the message queue.

jaeheung
  • 1,208
  • 6
  • 7