2011-07-15 12 views
7

सोते समय मैं QThread कैसे जगा सकता हूं?नींद में एक QThread जगाओ?

मेरे पास पृष्ठभूमि में चल रहा एक धागा है और अब उठता है और फिर कुछ छोटी चीजें करता है, हालांकि अगर मैं उस थ्रेड को नियंत्रित तरीके से रोकना चाहता हूं तो मुझे उसके द्वारा जागने के लिए इंतजार करना होगा उसे छोड़ने के लिए स्वयं। और चूंकि वह काफी देर तक सो रहा है, यह काफी परेशान हो सकता है।

यहां एक छोटा उदाहरण कोड है जो मूल समस्या दिखाता है।

चलिए इस धागे से शुरू करते हैं कि इस उदाहरण में 5 सेकंड तक सो जाता है और फिर बस एक बिंदु मुद्रित करता है।

#include <QDebug> 
#include "TestThread.h" 

void TestThread::run() 
{ 
    running = true; 
    while(running == true) 
    { 
     qDebug() << "."; 
     QThread::sleep(5); 
    } 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    running = false; 
} 

तब हमारे पास मुख्य है जो थ्रेड शुरू करता है और फिर उसे मार देता है।

#include <QDebug> 
#include "TestThread.h" 

int main(int argc, char *argv[]) 
{ 
    qDebug() << "Start test:"; 
    TestThread *tt = new TestThread(); 

    tt->start(); 
    sleep(2); 
    tt->stop(); 
    tt->wait(); 

    delete tt;  
} 

समस्या यह है कि tt-> प्रतीक्षा(); थ्रेड सो रहा है कि 5s इंतजार करना चाहिए। क्या मैं बस "नींद से जागने" की तरह कुछ कह सकता हूं ताकि वह जारी रख सके।

या ऐसा करने का कोई बेहतर तरीका है?

#include <QDebug> 
#include "TestThread.h" 

QMutex sleepMutex; 

void TestThread::run() 
{ 
    qDebug() << "Begin"; 
    //1. Start to lock 
    sleepMutex.lock(); 
    //2. Then since it is locked, we can't lock it again 
    // so we timeout now and then. 
    while(!sleepMutex.tryLock(5000)) 
    { 
     qDebug() << "."; 
    } 
    //4. And then we cleanup and unlock the lock from tryLock. 
    sleepMutex.unlock(); 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    //3. Then we unlock and allow the tryLock 
    // to lock it and doing so return true to the while 
    // so it stops. 
    sleepMutex.unlock(); 
} 

लेकिन यह QWaitCondition उपयोग करने के लिए बेहतर होगा:

/धन्यवाद


अद्यतन मैं इसे एक QMutex और tryLock के साथ काम मिल गया? या यह वही है?


अद्यतन: QMutex टूट जाता है, तो यह एक ही चलने कि शुरू होता है और उसे रोकने नहीं है, इसलिए यहाँ QWaitCondition साथ एक कोशिश है।

#include <QDebug> 
#include <QWaitCondition> 
#include "TestThread.h" 

QMutex sleepMutex; 

void TestThread::run() 
{ 
    qDebug() << "Begin"; 

    running = true; 
    sleepMutex.lock(); 
    while(!waitcondition.wait(&sleepMutex, 5000) && running == true) 
    { 
     qDebug() << "."; 
    } 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    running = false; 
    waitcondition.wakeAll(); 
} 

उत्तर

6

आप एक सरल sleep के बजाय एक QWaitCondition इस्तेमाल कर सकते हैं। यदि आपको अधिक नियंत्रण देता है।

उदाहरण यहाँ उपयोग: Wait Conditions Example

+0

अच्छा लगता है, लेकिन आपका मतलब क्या है? – Johan

+0

मैंने जो उदाहरण जोड़ा है उसे देखें। विचार है कि एक म्यूटेक्स को लॉक करना और अपनी नींद को बदलने के लिए प्रतीक्षा स्थिति की 'प्रतीक्षा (QMutex *, लंबा)' फ़ंक्शन का उपयोग करना है, और अपने 'स्टॉप()' फ़ंक्शन में 'wakeAll() 'या' wakeOne()' का उपयोग करें। आपका संपादन अच्छा नहीं है: आपको एक थ्रेड से 'लॉक()' और उसी म्यूटेक्स ऑब्जेक्ट पर किसी अन्य से अनलॉक() 'कॉल नहीं करना चाहिए। – Mat

+0

तो आप उसे कभी अनलॉक नहीं करते? आप "बूल रनिंग" रखते हैं तो लूप को रोकें? – Johan

1

मुझे नहीं लगता कि एक पोर्टेबल समाधान मौजूद है (हालांकि वहाँ कुछ आपरेशन प्रणालियों में कुछ सुविधाएं, POSIX संकेत की तरह हो सकता है) है। वैसे भी, क्यूटी ही इस तरह के साधन प्रदान नहीं करता है, इस प्रकार आप इसे पसंद

void TestThread::run() 
{ 
    running = true; 
    while(running == true) 
    { 
     qDebug() << "."; 
     // Quantize the sleep: 
     for (int i = 0; i < 5 && running; ++i) QThread::sleep(1); 
    } 
    qDebug() << "Exit"; 
} 

अनुकरण कर सकता है लेकिन सबसे अच्छा समाधान अभी भी एक QWaitCondition, के रूप में चटाई द्वारा बताया होगा।

संबंधित मुद्दे