簡體   English   中英

std :: mutex無法正確鎖定std :: cout

[英]std::mutex not locking properly for std::cout

我正在學習C ++ 11中的多線程,並且嘗試了這個簡單的測試,但是輸出不是我期望的。

#include <thread>
#include <iostream>
#include <mutex>

int main() {
    auto function = [](int x) {
        std::mutex m;
        m.try_lock();
        std::cout << "Hello" << x << std::endl;
        m.unlock();
        return;
    };
    std::thread t1(function , 1);
    std::thread t2(function, 2);
    std::thread t3(function, 3);
    std::thread t4(function, 4);    

    t1.join();
    t2.join();
    t3.join();
    t4.join();

    std::cin.get();
    return 0;
}

我期望輸出為:

Hello1
Hello2
Hello3
Hello4

(也許不是按此順序,而是每個問候和數字在單獨的行中)

相反,我得到了這樣的東西:

HelloHello21
Hello3
Hello4

要么

HelloHello2
1
Hello3
Hello4

除了互斥鎖顯然不能正確鎖定之外,還有一個令人困惑的問題是,總是Hello2被切成兩半。

編輯:如果有任何區別,請在VS2015中完成(不應該因為它是全部標准?)

您需要使用static ,因為所有線程都必須訪問相同的互斥對象。 另外,如果在您unlock()之前引發了異常, try_lock() (或lock() )也會引起問題。 std::lock_guard<>()是一種更安全的方法,因此建議使用它,因為它超出函數范圍時將被釋放,無論是通過函數返回還是通過異常。

嘗試對該功能進行以下修訂:

auto function = [](int x) {
    static std::mutex m;
    std::lock_guard<std::mutex> mylock(m);
    std::cout << "Hello" << x << std::endl;
    return;
};

有關更多信息,請參見http://en.cppreference.com/w/cpp/thread/lock_guard

另外,如果您認為將來可能會更改互斥鎖類型(或只是想花哨),則可以使用推斷的模板類型設置互斥鎖:

std::lock_guard<decltype(m)> mylock(m);

try_lock()不一定鎖定互斥體。 它可能會鎖定互斥鎖,但可能不會。 它只會嘗試鎖定互斥鎖。 如果已被鎖定,則它不會等到互斥鎖被解鎖后才返回,表明已發生這種情況。

因此,實際上,您的代碼最終無法有效地以任何形式,形狀,物質或形式同步其輸出。

如果您確實想鎖定互斥鎖,請使用lock()而不是try_lock()

編輯:正如其他人指出的那樣,您的代碼有效地為每個線程創建了一個單獨的互斥體,因此您也需要使該互斥體成為static

暫無
暫無

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

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