मेरे पास निम्नलिखित तरीके से लागू एक लाइव ऑब्जेक्ट है। इसका उपयोग पृष्ठभूमि में लंबे कार्यों को निष्पादित करने के लिए किया जाता है। मुख्य धागा सार्वजनिक स्लॉट (यानी DoTask) को सिग्नल भेजकर कार्यों को आमंत्रित करता है। यहां एक छीन लिया गया उदाहरण है (परीक्षण नहीं किया गया)।बिना कनेक्शन के स्लॉट विधि को आमंत्रित करें?
class MyTask : public QObject
{
Q_OBJECT
public:
MyTask();
~MyTask();
public slots:
void doTask(int param);
private slots:
void stated();
signals:
void taskCompleted(int result);
private:
QThread m_thread;
};
MyTask::MyTask()
{
moveToThread(&m_thread);
connect(&m_thread, SIGNAL(started()), this, SLOT(started()));
m_thread.start();
}
MyTask::~MyTask()
{
// Gracefull thread termination (queued in exec loop)
if(m_thread.isRunning())
{
m_thread.quit();
m_thread.wait();
}
}
void MyTask::started()
{
// initialize live object
}
void MyTask::doTask(int param)
{
sleep(10);
emit taskCompleted(param*2);
}
यह (चाहिए) के रूप में काम (doTask के रूप में रूप में लंबे समय की उम्मीद) एक संकेत से शुरू हो जाती है। लेकिन यदि मुख्य धागा सीधे टाटास्क() को कॉल करता है तो इसे मुख्य थ्रेड द्वारा निष्पादित किया जाएगा। कुछ कार्यों के लिए, मैं लाइव ऑब्जेक्ट के धागे द्वारा निष्पादन को लागू करना चाहता हूं, भले ही स्लॉट विधि को सीधे कहा जाता है।
मैं यह जांचने के लिए डॉट टास्क() के सामने कोड जोड़ सकता हूं कि वर्तमान धागा m_thread है, जिस स्थिति में यह विधि निष्पादित करता है। यदि नहीं, तो मैं चाहता हूं कि DoTask() 'इस' के लिए एक सिग्नल उत्सर्जित करता है ताकि mTthread exec लूप में doTask() का आविष्कार किया जा सके और जितनी जल्दी हो सके इसे निष्पादित किया जाए।
मैं यह कैसे कर सकता हूं?
संपादित करें: प्रस्तावित उत्तर के आधार पर, यह नया कोड है। DoTask विधि अब लाइव ओब्जेट के थ्रेड द्वारा निष्पादन का प्रतिनिधित्व करती है, भले ही मुख्य थ्रेड द्वारा सीधे कहा जाता है। सिग्नल द्वारा बुलाया अभी भी उम्मीद के रूप में काम करता है।
class MyTask : public QObject
{
Q_OBJECT
public:
explicit MyTask(QObject *parent = 0);
~MyTask();
public slots:
void doTask(int param);
private slots:
void doTaskImpl(int param);
signals:
void taskCompleted(int result);
private:
QThread m_thread;
};
MyTask::MyTask(QObject *parent) : QObject(parent)
{
moveToThread(&m_thread);
m_thread.start();
}
MyTask::~MyTask()
{
// Gracefull thread termination (queued in exec loop)
if(m_thread.isRunning())
{
m_thread.quit();
m_thread.wait();
}
}
void MyTask::doTask(int param)
{
QMetaObject::invokeMethod(this, "doTaskImpl", Q_ARG(int, param));
}
void MyTask::doTaskImpl(int param)
{
// Do the live oject's asynchronous task
sleep(10);
emit taskCompleted(param*2);
}
यह एक साधारण थ्रेड में एसिंक्रोनस विधि निष्पादन का समर्थन करने के लिए सबसे सरल कार्यान्वयन है। जैसे ही धागा शुरू होता है, doTask() विधियों के आविष्कार कतारबद्ध और संसाधित किए जाएंगे। जब ऑब्जेक्ट थ्रेड से बुलाया जाता है, तो इसे तुरंत निष्पादित किया जाएगा (कतारबद्ध नहीं)।
ध्यान दें कि प्रारंभ() संकेत थ्रेड शुरू होने पर ही उत्सर्जित होता है। इसका मतलब है कि थ्रेड शुरू होने से पहले कतारबद्ध() विधि आवेदक प्रारंभ() विधि स्लॉट लागू होने से पहले निष्पादित होगा। यही कारण है कि मैंने इसे प्रारंभिक कार्यान्वयन से हटा दिया। इस प्रकार ऑब्जेक्ट प्रारंभिक रूप से कन्स्ट्रक्टर में अधिमानतः किया जाना चाहिए।
मैं एक समस्या यहाँ देख नहीं है: डॉक्स का कहना है कि आप अगर यह एक और धागा करने के लिए एक वस्तु को स्थानांतरित नहीं किया जा सकता एक माता पिता है यदि आपका टाटा माता-पिता के साथ बनाया गया है तो क्या आपका कोड काम करता है? – andref
एक समान प्रश्न का उत्तर पहले ही दिया गया था [क्यूटी + कस्टम सी ++ कोड से अलग थ्रेड में चलने वाले स्लॉट को कैसे कॉल करें] (http: // stackoverflow।com/प्रश्न/1144240/क्यूटी-कैसे-टू-कॉल-स्लॉट-से-कस्टम सी कोड से चल में एक-अलग धागा)। – Trilarion