Qt修炼手册12_线程同步与线程等待条件
生活随笔
收集整理的這篇文章主要介紹了
Qt修炼手册12_线程同步与线程等待条件
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.同步線程:何為同步?
參考百度百科:1.1 線程
線程是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分配的基本單位。一個(gè)進(jìn)程可以有多個(gè)線程,一個(gè)線程必須有一個(gè)父進(jìn)程,線程自己不擁有系統(tǒng)資源,只有運(yùn)行必須的一些數(shù)據(jù)結(jié)構(gòu),但它可以與同屬一個(gè)進(jìn)程的其他線程共享進(jìn)程所擁有的全部資源,一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。1.2 多線程
由于線程之間的相互制約,致使線程在運(yùn)行中呈現(xiàn)出間斷性,線程也有就緒、阻塞、和運(yùn)行3種基本狀態(tài),所以,在一個(gè)進(jìn)程中可以創(chuàng)建幾個(gè)線程來提高程序的執(zhí)行效率,并且有些程序還通過采用多線程技術(shù)來同事執(zhí)行多個(gè)不同的代碼模塊。?在一般情況下,創(chuàng)建一個(gè)線程是不能提高程序的執(zhí)行效率的,所以要創(chuàng)建多個(gè)線程。但是多個(gè)線程同時(shí)運(yùn)行的時(shí)候可能調(diào)用線程函數(shù),在多個(gè)線程同時(shí)對同一個(gè)內(nèi)存地址進(jìn)行寫入,由于CPU時(shí)間調(diào)度上的問題,寫入數(shù)據(jù)會被多次的覆蓋,所以就要使線程同步。
1.3 線程同步
即當(dāng)有一個(gè)線程在對內(nèi)存進(jìn)行操作時(shí),其他線程都不可以對這個(gè)內(nèi)存地址進(jìn)行操作,直到該線程完成操作,其他線程才能對該內(nèi)存地址進(jìn)行操作,而其他線程又處于等待狀態(tài),目前實(shí)現(xiàn)線程同步的方法有很多,臨界區(qū)對象就是其中一種。臨界區(qū)的使用步驟:
1.初始化一個(gè)CURITY_ATTRIBUTES結(jié)構(gòu),在臨界區(qū)對象之前,需要定于全局CURITY_ATTRIBUTES結(jié)構(gòu)變量,在調(diào)用CreateThread函數(shù)前調(diào)用InitializeCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函數(shù)初始化臨界區(qū)對象。?
2.申請進(jìn)入一個(gè)臨界區(qū)。在線程函數(shù)中要對保護(hù)的數(shù)據(jù)進(jìn)行操作前,可以通過調(diào)用 EnterCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函數(shù)申請進(jìn)入臨界區(qū),由于在同一時(shí)間內(nèi),只允許一個(gè)線程進(jìn)入臨界區(qū),所以在申請的時(shí)候如果有一個(gè)線程進(jìn)入到臨界區(qū),則該函數(shù)就會一直等到那個(gè)線程執(zhí)行完臨界區(qū)代碼。?
3.離開臨界區(qū)。當(dāng)執(zhí)行完臨界區(qū)代碼后,需要調(diào)用LeaveCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函數(shù)把臨界區(qū)交還給系統(tǒng)。?
4.刪除臨界區(qū),當(dāng)不需要臨界區(qū)是可以調(diào)用DeleteCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函數(shù)將臨界區(qū)對象刪除。
1.4 怎么理解同步?
同步就是協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行。如:你說完,我再說。“同”字從字面上容易理解為一起動作其實(shí)不是,“同”字應(yīng)是指協(xié)同、協(xié)助、互相配合。如進(jìn)程、線程同步,可理解為進(jìn)程或線程A和B一塊配合,A執(zhí)行到一定程度時(shí)要依靠B的某個(gè)結(jié)果,于是停下來,示意B運(yùn)行;B依言執(zhí)行,再將結(jié)果給A;A再繼續(xù)操作。所謂同步,就是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回,同時(shí)其它線程也不能調(diào)用這個(gè)方法。按照這個(gè)定義,其實(shí)絕大多數(shù)函數(shù)都是同步調(diào)用(例如sin, isdigit等)。但是一般而言,我們在說同步、異步的時(shí)候,特指那些需要其他部件協(xié)作或者需要一定時(shí)間完成的任務(wù)。例如Window API函數(shù)SendMessage。該函數(shù)發(fā)送一個(gè)消息給某個(gè)窗口,在對方處理完消息之前,這個(gè)函數(shù)不返回。當(dāng)對方處理完畢以后,該函數(shù)才把消息處理函數(shù)所返回的LRESULT值返回給調(diào)用者。在多線程編程里面,一些敏感數(shù)據(jù)不允許被多個(gè)線程同時(shí)訪問,此時(shí)就使用同步訪問技術(shù),保證數(shù)據(jù)在任何時(shí)刻,最多有一個(gè)線程訪問,以保證數(shù)據(jù)的完整性。
2.線程等待條件
應(yīng)用程序運(yùn)行多線程時(shí),無法保證哪個(gè)線程先運(yùn)行,等待條件就等于同步線程。 例如,假如應(yīng)用程序中有兩個(gè)線程同時(shí)運(yùn)行。第一個(gè)線程進(jìn)行工作,第二個(gè)線程則處于待機(jī)狀態(tài),直到第一個(gè)線程完成到一定程度立即調(diào)用第二個(gè)線程,第二個(gè)線程才會開始工作。很明顯這就是協(xié)同~ 使用等待條件可以實(shí)現(xiàn)上述線程間的同步。為了使用等待條件,Qt提供了QWaitCondition類。QWaitCondition類使用函數(shù)wait()使線程進(jìn)入阻塞狀態(tài),使用waitOne()或waitAll()則可以講線程從阻塞狀態(tài)喚醒。 需要注意的是,QWaitCondition在線程中與互斥體一起使用。 #include <QtWidgets/QApplication> #include <QWaitCondition> #include <QMutex> #include <QThread>QMutex mutex; //各線程的全局量 QWaitCondition incNumber; //各線程的全局量 int numUsed; //producer 和 consumer 的共享變量class Producer : public QThread { public:Producer() {} protected:void run(){for(int i = 0 ; i < 10 ; i++){//sleep(1);mutex.lock(); //注意此互斥量生產(chǎn)者與消費(fèi)者共享++numUsed;incNumber.wakeAll();qDebug("Producer-numUsed : %d", numUsed);mutex.unlock();}} };class Consumer : public QThread { public:Consumer(){} protected:void run(){for(int i = 0 ; i < 10 ; i++){mutex.lock();//incNumber.wait(&mutex); //此處mutex與生產(chǎn)者是同一個(gè),所以會等待生產(chǎn)者線程qDebug("Consumer-numUsed : %d", numUsed);mutex.unlock(); }} };int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);Producer producer;Consumer consumer;producer.start();consumer.start();return a.exec(); }- //Sleep(1);//incNumber.wait(&mutex);?輸出結(jié)果:
生產(chǎn)者消費(fèi)者線程同時(shí)處于激活狀態(tài)。盡在互斥量作用下交替搶占資源。
- sleep(1); //incNumber.wait(&mutex);輸出結(jié)果:
- sleep(1); incNumber.wait(&mutex);輸出結(jié)果:
- //sleep(1); ?incNumber.wait(&mutex);輸出結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的Qt修炼手册12_线程同步与线程等待条件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5参考手册
- 下一篇: 飞秋-程序的找工作之苦