簡體   English   中英

其他線程正在等待時如何阻塞線程

[英]How to block a thread while other threads are waiting

我有一個非常具體的問題要解決。 我很確定世界上其他人已經遇到並解決了它,但是我還沒有找到任何解決方案。

這里是 :

  • 我有一個線程從隊列中彈出命令並異步執行它們
  • 我可以從任何其他線程調用函數來同步執行命令,繞過隊列機制,返回結果,並優先執行(在當前執行結束之后)。
  • 我有一個互斥鎖來保護命令的執行,所以一次只能執行一個。問題是,對於一個簡單的互斥鎖,我不確定在沖突時同步調用會在異步線程之前獲得互斥鎖。 實際上,我們的測試表明分配是非常不公平的,並且異步線程始終會獲勝。

因此,我想在有一個同步調用等待時阻塞異步線程。 我事先不知道可以進行多少次同步調用,並且我不控制進行調用的線程(因此無法使用線程池進行任何解決方案)。

我正在使用C ++和Microsoft庫。 我知道基本的同步對象,但是也許有一個更高級的對象或方法適合我所不知道的問題。

我願意接受任何想法!

好的,所以我終於有機會關閉它。 我嘗試了此處和鏈接中提出的一些解決方案。 最后,我將用於執行命令的互斥鎖與等待同步調用的計數器結合在一起(該計數器當然也受互斥鎖保護)。 異步線程在嘗試獲取互斥之前先檢查計數器,然后等待計數器為0。此外,為避免出現睡眠循環,我添加了一個在計數器設置為0時設置的事件。異步線程等待嘗試獲取互斥對象之前發生此事件。

void incrementSyncCounter()
{
    DLGuardThread guard(_counterMutex);
    _synchCount++;
}

void decrementSyncCounter()
{
    DLGuardThread guard(_counterMutex);
    _synchCount--;

    // If the counter is 0, it means that no other sync call is waiting, so we notify the main thread by setting the event
    if(_synchCount == 0)
    {
        _counterEvent.set();
    }
}

unsigned long getSyncCounter()
{
    DLGuardThread guard(_counterMutex);
    return _synchCount;
}

bool executeCommand(Command* command)
{
    // Increment the sync call counter so the main thread can be locked while at least one sync call is waiting
    incrementSyncCounter();

    // Execute the command using mutex protection
    DLGuardThread guard(_theCommandMutex);
    bool res = command->execute();
    guard.release();

    // Decrement the sync call counter so the main thread can be unlocked if there is no sync call waiting
    decrementSyncCounter();

    return res;
}

void main ()
{
    [...]
    // Infinite loop
    while(!_bStop)
    {
        // While the Synchronous call counter is not 0, this main thread is locked to give priority to the sync calls.
        // _counterEvent will be set when the counter is decremented to 0, then this thread will check the value once again to be sure no other call has arrived inbetween.
        while(getSyncCounter() > 0)
        {
            ::WaitForSingleObject (_counterEvent.hEvent(), INFINITE);
        }

        // Take mutex
        DLGuardThread guard(_theCommandMutex);

        status = command->execute();

        // Release mutex
        guard.release();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM