簡體   English   中英

使用x86程序集的信號量實現

[英]Semaphore implementation using x86 assembly

我對信號量實現方案感興趣,並且我了解到在x86中,我們可以使用“鎖定前綴”來實現原子操作,我想用它來實現一個互斥鎖,我知道C ++ 11現在有標准的互斥鎖,但我想實現自己的。 這是我的代碼:

#include <iostream>
#include <thread>
#include <vector>

struct Semaphore
{
private:
    int s;
public:
    Semaphore( int s ) : s(s){}
    void wait()
    {
        int *p = &s;
        _asm
        {
            mov eax, p
            lock dec DWORD PTR [eax]
    begin : mov ebx, DWORD PTR [eax]
            cmp ebx, 0
            jl begin
        };
    }

    void signal()
    {
        int *p = &s;
        _asm
        {
            mov eax, p
            lock inc DWORD PTR [eax]
        };
    }
} s(1);

void print()
{
    s.wait();
    std::cout << "Print Thread " << std::this_thread::get_id() << std::endl;
    s.signal();
}

int main( int argc, char* argv )
{
    std::vector< std::thread > vec;
    int n = 3;
    for( int i = 0; i < n; ++i ) vec.push_back( std::thread( print ) );
    for( int i = 0; i < n; ++i ) vec[i].join();

    return 0;
}

問題是,當有兩個線程時,代碼運行良好,而在3個線程的情況下,程序似乎陷入死鎖狀態,任何人都可以解釋原因或給我一些關於如何在x86機器上實現的建議?

你的wait實際上是一個自旋鎖 - 當鎖被爭用時,它將(嘗試)使用100%的CPU,直到其他線程釋放信號量。 不幸的是,由於它使用了100%的CPU,這可以防止其他線程獲得CPU時間,因此您可以獲得接近死鎖的東西。

猜測,你可能正在使用雙核CPU。 在這種情況下,即使自旋鎖處於緊密循環中,其他線程也可以全速運行,浪費CPU時間。 當你獲得比可用CPU核心更多的線程時,事情就會停滯不前。

如果您有充分的理由相信信號量會很快變清(在這種情況下您希望避免任務切換的開銷),則自旋鎖可能很有用。 但是,在典型情況下,您希望限制“旋轉”所花費的時間,因此您的循環看起來像:

        mov ecx, 100
begin : mov ebx, DWORD PTR [eax]
        test ebx, ebx
        loopnz begin

然后,在它跳出循環之后,檢查信號量是否已清除,或者是否達到了限制(在這種情況下為100次迭代)。 如果達到了限制,則調用調度程序讓其他線程運行(並在此線程再次運行時重新嘗試等待)。

您創建的代碼不是信號量的正確實現。 信號量應該將等待任務放入信號量的等待隊列中; 之后,在信號量再次發出信號之前,它的代碼不會運行; 當信號量發出信號時,一個等待的線程被喚醒。 信號量代碼的一半在內核中,有關如何訪問它的詳細信息在線程庫實現中。 因此,要正確地實現信號量,在C ++中,您需要做一些更復雜的事情。 或者您可以編寫自己的操作系統。

此外,您沒有說明您正在使用什么編譯器,但您的編譯器可能會過於激進地優化asm子句。

這里有很多問題。 這是兩個。

  1. 您的wait()例程無條件地減少計數器。 如果您有兩個服務員,那么您的計數將為-2,並且在任何服務員停止等待之前您將需要兩個信號。

  2. 寫入的信號量代碼完全取決於調度程序。 因此,根據調度程序和服務員和信號器的優先級,完全有可能等待任務(繁忙的循環)永遠不會屈服於另一個執行上下文。

希望這可以幫助。

是的,我承認沒有操作系統或機器的幫助我無法實現自己的版本,所以我嘗試使用C ++ 11標准實現一個,我發現斯坦福大學的課程提供了一個解決方案,我想與任何需要它的人分享,這里是鏈接: http//www.stanford.edu/class/cs110/lectures/18-threading-and-semaphores.html#(3)

暫無
暫無

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

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