मुझे क्यूटी थ्रेड और कनेक्शन के साथ कुछ परेशानी मिली है। मुझे इस विषय पर कई ट्यूटोरियल और चर्चाएं मिलीं, मैंने धागा बनाने के लिए this tutorial का पालन किया। लेकिन मुझे अभी भी समस्या है, कि थ्रेड पर प्रतीक्षा() कॉलिंग कभी वापस नहीं आती है और यूआई फ्रीज करता है।क्यूटीएचड :: प्रतीक्षा() सीधे कनेक्शन का उपयोग किए बिना वापस नहीं आती है
ऐसा ही एक सवाल यहाँ से पहले (दूसरा उदाहरण) से पूछा गया था: Qt connection type between threads: why does this work?
सवाल का पिछला संपादन में, लेखक का उल्लेख है कि वह एक गतिरोध पैदा कर दिया था। मुझे लगता है, मैं अपने आवेदन में वही करता हूं। लेकिन मैं अभी भी समझ में नहीं आता, ऐसा क्यों होता है। suggested article पढ़ना मुझे समझने में मदद नहीं करता था। मुझे अभी बात मिल गई है कि डेडलॉक्स हो सकते हैं, लेकिन मुझे नहीं पता, यह वहां क्या है या मेरे मामले में।
मैंने एक उदाहरण भी बनाया है जो मूल समस्या में कम हो गया है। इस प्रश्न के निचले हिस्से में कोड पाएं।
तो मेरे प्रश्न हैं: मेरे उदाहरण में डेडलॉक का कारण क्या है? कनेक्शन को सीधा कनेक्शन के बिना कोई समाधान है?
मैं वास्तव में किसी भी संकेत की सराहना करता हूं।
धन्यवाद!
संपादित करें:
क्योंकि टिप्पणियों के मैं इसे करने की कोशिश एक संकेत के माध्यम से रोक अनुरोध भेजने के लिए और मैं धागा पाश में एक QCoreApplication :: processEvents() कॉल गयी। लेकिन मुख्य समस्या अभी भी वही है।
EDIT2:
मैं, एक स्वीकार्य समाधान पाया घटना के बारे में थोड़ा और सोच के बाद लूप:
thread.requestStop();
// now instead of using wait(), we poll and keep the event loop alive
// polling is not nice, but if it does not take a very long time
// for the thread to finish, it is acceptable for me.
while (thread.isRunning())
{
// This ensures that the finished() signal
// will be processed by the thread object
QCoreApplication::processEvents();
}
यह वास्तव में काम करता है और कार्यकर्ता ही नियंत्रित करता है कैसे काम करना बंद कर।
इसके साथ आने के बाद, मेरे पास ठंडक मुद्दे के लिए भी एक स्पष्टीकरण है: कॉलिंग प्रतीक्षा मुख्य धागे को व्यस्त या निलंबित रखने लगता है, इसलिए यह किसी भी घटना को संसाधित नहीं करता है। चूंकि थ्रेड ऑब्जेक्ट मुख्य थ्रेड में रहता है, इसलिए थ्रेड का पूरा() सिग्नल प्राप्त होता है लेकिन कभी संसाधित नहीं होता है।
मेरी अंतर्निहित धारणा, कि thread.wait() अभी भी ईवेंट लूप को काम करेगा, स्पष्ट रूप से गलत था। लेकिन फिर, QThread :: प्रतीक्षा() फ़ंक्शन के लिए क्या अच्छा है?!
यह सिर्फ एक सिद्धांत है, लेकिन शायद किसी को यहाँ की पुष्टि या इसे झूठा साबित कर सकते हैं ...
संपादित 3 (अंतिम समाधान):
this small article पढ़ रहे हैं और एक उपवर्गीकरण समाधान implmenting के बाद, मुझे लगता है कि कि यह इस विशेष समस्या के लिए बेहतर है। इवेंट लूप की कोई ज़रूरत नहीं है और मैं एक अलग थ्रेड पर सीधे कॉल के साथ ठीक हूं और म्यूटेक्स सुरक्षा का उपयोग कर रहा हूं। यह कम कोड, समझने में आसान और डीबग करने में आसान है।
मुझे लगता है कि मैं केवल गैर-सबक्लासिंग रणनीति का उपयोग करूंगा, अगर थ्रेड के साथ और अधिक बातचीत हो तो बस शुरू करें और रोकें।
मेरे उदाहरण
कम शायद मैं कहना चाहिए, कि मैं धागा, क्योंकि अपने मूल आवेदन में, मैं बाद में फिर से शुरू करना चाहते हैं नहीं हटाते हैं, तो वास्तव में यह रोक यह रोक का मतलब है।
worker.h:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject* parent = NULL);
public slots:
void doWork();
void requestStop();
signals:
void finished();
private:
bool stopRequested;
QMutex mutex;
};
#endif // WORKER_H
worker.cpp:
#include "worker.h"
#include <QThread>
#include <iostream>
using namespace std;
Worker::Worker(QObject *parent)
: stopRequested(false)
{
}
void Worker::doWork()
{
static int cnt = 0;
// local loop control variable
// to make the usage of the mutex easier.
bool stopRequesteLocal = false;
while (!stopRequesteLocal)
{
cout << ++cnt << endl;
QThread::msleep(100);
mutex.lock();
stopRequesteLocal = stopRequested;
mutex.unlock();
}
cout << "Finishing soon..." << endl;
QThread::sleep(2);
emit finished();
}
void Worker::requestStop()
{
mutex.lock();
stopRequested = true;
mutex.unlock();
}
मुख्य कार्यक्रम:
#include <QCoreApplication>
#include <QThread>
#include <QtCore>
#include <iostream>
#include "worker.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThread thread;
Worker worker;
QObject::connect(&thread, SIGNAL(started()), &worker, SLOT(doWork()));
// this does not work:
QObject::connect(&worker, SIGNAL(finished()), &thread, SLOT(quit()));
// this would work:
//QObject::connect(&worker, SIGNAL(finished()), &thread, SLOT(quit()), Qt::DirectConnection);
// relocating the moveToThread call does not change anything.
worker.moveToThread(&thread);
thread.start();
QThread::sleep(2);
worker.requestStop();
cout << "Stop requested, wait for thread." << endl;
thread.wait();
cout << "Thread finished" << endl;
// I do not know if this is correct, but it does not really matter, because
// the program never gets here.
QCoreApplication::exit(0);
}
'नींद' एक क्यूटी में सुरक्षित है के रूप में सवाल पाठ करने के लिए अपने खुद के answere जोड़ा, तुम कैसे QThread :: नींद (2) कॉल कर सकते हैं; ?? – UmNyobe
मुझे नहीं पता। मैं बस यह करता हूं और यह काम करता है। ;) – Kanalpiroge
यह संभव नहीं है :) क्या आपने क्यूटी स्रोत संपादित किया है? –