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