第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Mutex示例/教程?

Mutex示例/教程?

C++ C
慕少森 2019-10-14 10:22:59
我是多線程的新手,并試圖了解互斥鎖的工作原理。做了很多谷歌搜索,我發(fā)現(xiàn)了一個不錯的教程,但是它仍然對它的工作方式產(chǎn)生了一些疑問,因為我創(chuàng)建了自己的程序,其中鎖不起作用?;コ饬康囊环N絕對不直觀的語法pthread_mutex_lock( &mutex1 );是,當(dāng)我真正想要鎖定的是其他變量時,它看起來像互斥量被鎖定了。這種語法是否意味著鎖定互斥鎖會鎖定代碼區(qū)域,直到互斥鎖解鎖為止?那么線程如何知道該區(qū)域已鎖定?[ 更新:線程知道該區(qū)域已被 Memory Fencing 鎖定 ]。難道這種現(xiàn)象不應(yīng)該稱為臨界區(qū)嗎?[ 更新:關(guān)鍵部分對象僅在Windows中可用,其中這些對象比互斥對象快,并且僅對實現(xiàn)該對象的線程可見。否則,關(guān)鍵部分僅指由互斥體保護(hù)的代碼區(qū)域 ]簡而言之,能否請您提供最簡單的互斥體示例程序以及有關(guān)其工作原理的最簡單的解釋?我相信這將對其他許多新手有所幫助。
查看完整描述

3 回答

?
隔江千里

TA貢獻(xiàn)1906條經(jīng)驗 獲得超10個贊

盡管互斥鎖可以用于解決其他問題,但它們存在的主要原因是提供相互排斥,從而解決了所謂的競爭條件。當(dāng)兩個(或多個)線程或進(jìn)程試圖同時訪問同一變量時,我們就有競爭條件的可能性??紤]以下代碼


//somewhere long ago, we have i declared as int

void my_concurrently_called_function()

{

  i++;

}

該函數(shù)的內(nèi)部看起來很簡單。這只是一個陳述。但是,典型的偽匯編語言等效項可能是:


load i from memory into a register

add 1 to i

store i back into memory

因為在i上執(zhí)行增量操作都需要使用等效的匯編語言指令,所以我們說對i進(jìn)行增量運算是一種非大氣操作。原子操作是可以在硬件上完成的操作,保證一旦指令執(zhí)行開始就不會被中斷。遞增i由3個原子指令鏈組成。在多個線程正在調(diào)用該函數(shù)的并發(fā)系統(tǒng)中,當(dāng)線程在錯誤的時間讀取或?qū)懭霑r會出現(xiàn)問題。假設(shè)我們有兩個同時運行的線程,一個線程緊接著另一個線程調(diào)用該函數(shù)。我們還假設(shè)我們已將i初始化為0。還假設(shè)我們有很多寄存器,并且兩個線程使用的寄存器完全不同,因此不會發(fā)生沖突。這些事件的實際時間可能是:


thread 1 load 0 into register from memory corresponding to i //register is currently 0

thread 1 add 1 to a register //register is now 1, but not memory is 0

thread 2 load 0 into register from memory corresponding to i

thread 2 add 1 to a register //register is now 1, but not memory is 0

thread 1 write register to memory //memory is now 1

thread 2 write register to memory //memory is now 1

發(fā)生的事情是我們有兩個線程同時遞增i,我們的函數(shù)被調(diào)用了兩次,但結(jié)果與該事實不一致??雌饋碓摵瘮?shù)僅被調(diào)用一次。這是因為原子性在計算機級別“中斷”,這意味著線程可以互相中斷或在錯誤的時間一起工作。


我們需要一種機制來解決這個問題。我們需要對以上說明進(jìn)行一些排序。一種常見的機制是阻止除一個線程外的所有線程。Pthread互斥使用此機制。


任何必須執(zhí)行一些代碼行的線程(可能會同時不安全地修改其他線程的共享值(使用電話與妻子交談))必須首先獲得互斥鎖。這樣,任何需要訪問共享數(shù)據(jù)的線程都必須通過互斥鎖。只有這樣,線程才能執(zhí)行代碼。這部分代碼稱為關(guān)鍵部分。


一旦線程執(zhí)行了關(guān)鍵部分,就應(yīng)該釋放互斥鎖,以便另一個線程可以獲取互斥鎖。


當(dāng)考慮人類尋求對真實物理對象的專有訪問權(quán)時,具有互斥體的概念似乎有些奇怪,但是在編程時,我們必須是故意的。并發(fā)線程和流程沒有我們所進(jìn)行的社會和文化養(yǎng)育,因此我們必須強迫它們很好地共享數(shù)據(jù)。


因此,從技術(shù)上講,互斥鎖是如何工作的?難道它沒有像我們前面提到的那樣遭受同樣的比賽條件嗎?pthread_mutex_lock()難道不是簡單地增加一個變量就復(fù)雜嗎?


從技術(shù)上講,我們需要一些硬件支持來幫助我們。硬件設(shè)計師為我們提供了機器指令,這些指令不僅可以完成一件事,而且必須保證是原子的。這種指令的經(jīng)典示例是測試設(shè)置(TAS)。嘗試獲取資源鎖時,我們可能會使用TAS來檢查內(nèi)存中的值是否為0。如果是,則表明我們正在使用該資源,并且我們什么也不做(或更準(zhǔn)確地說,是,我們會通過某種機制等待。pthreads互斥鎖會將我們放入操作系統(tǒng)的特殊隊列中,并在資源可用時通知我們。Dumber系統(tǒng)可能會要求我們執(zhí)行緊密的自旋循環(huán),一遍又一遍地測試條件) 。如果內(nèi)存中的值不為0,則TAS無需使用任何其他指令即可將位置設(shè)置為0以外的值。它' 就像將兩個匯編指令合并為1來賦予我們原子性。因此,一旦開始測試和更改值(如果適當(dāng)?shù)脑挘┚筒荒苤袛?。我們可以在這樣的指令之上構(gòu)建互斥體。


注意:某些部分可能與以前的答案類似。我接受了他的編輯邀請,他更喜歡原來的方式,所以我保留了自己的作品,并注入了一點點措辭。


查看完整回答
反對 回復(fù) 2019-10-14
?
慕標(biāo)5832272

TA貢獻(xiàn)1966條經(jīng)驗 獲得超4個贊

我最近偶然發(fā)現(xiàn)了這篇文章,并認(rèn)為它需要標(biāo)準(zhǔn)庫的c ++ 11互斥量(即std :: mutex)的更新解決方案。


我在下面粘貼了一些代碼(我使用互斥鎖的第一步-我在W32上通過HANDLE,SetEvent,WaitForMultipleObjects等學(xué)習(xí)了并發(fā)性)。


因為這是我第一次嘗試std :: mutex和朋友,所以我很樂意看到評論,建議和改進(jìn)!


#include <condition_variable>

#include <mutex>

#include <algorithm>

#include <thread>

#include <queue>

#include <chrono>

#include <iostream>



int _tmain(int argc, _TCHAR* argv[])

{   

    // these vars are shared among the following threads

    std::queue<unsigned int>    nNumbers;


    std::mutex                  mtxQueue;

    std::condition_variable     cvQueue;

    bool                        m_bQueueLocked = false;


    std::mutex                  mtxQuit;

    std::condition_variable     cvQuit;

    bool                        m_bQuit = false;



    std::thread thrQuit(

        [&]()

        {

            using namespace std;            


            this_thread::sleep_for(chrono::seconds(5));


            // set event by setting the bool variable to true

            // then notifying via the condition variable

            m_bQuit = true;

            cvQuit.notify_all();

        }

    );



    std::thread thrProducer(

        [&]()

        {

            using namespace std;


            int nNum = 13;

            unique_lock<mutex> lock( mtxQuit );


            while ( ! m_bQuit )

            {

                while( cvQuit.wait_for( lock, chrono::milliseconds(75) ) == cv_status::timeout )

                {

                    nNum = nNum + 13 / 2;


                    unique_lock<mutex> qLock(mtxQueue);

                    cout << "Produced: " << nNum << "\n";

                    nNumbers.push( nNum );

                }

            }

        }   

    );


    std::thread thrConsumer(

        [&]()

        {

            using namespace std;

            unique_lock<mutex> lock(mtxQuit);


            while( cvQuit.wait_for(lock, chrono::milliseconds(150)) == cv_status::timeout )

            {

                unique_lock<mutex> qLock(mtxQueue);

                if( nNumbers.size() > 0 )

                {

                    cout << "Consumed: " << nNumbers.front() << "\n";

                    nNumbers.pop();

                }               

            }

        }

    );


    thrQuit.join();

    thrProducer.join();

    thrConsumer.join();


    return 0;

}


查看完整回答
反對 回復(fù) 2019-10-14
  • 3 回答
  • 0 關(guān)注
  • 655 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號