簡體   English   中英

多線程應用程序無輸出

[英]Multithreading application has no output

我正在做一個處理多線程運動的應用程序,假設我們有10輛車,並且有一個停車場,最多可容納5輛車。如果一輛車不能停車,它會等到有空房間。
我正在使用c ++ 11線程執行此操作:

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

using namespace std;

int cars=0;
int max_cars=5;
mutex cars_mux;
condition_variable cars_cond;

bool pred()
{
    return cars< max_cars;
}

void task()
{
    unique_lock<mutex> lock(cars_mux);
    while(true)
    {
        cars_mux.lock();
        cars_cond.wait(lock,pred);
        cars++;
        cout << this_thread::get_id() << " has parked" << endl;
        cars_mux.unlock();
        this_thread::sleep_for(chrono::seconds(1));  // the cars is parked and waits some time before going away
        cars_mux.lock();
        cars--;
        cars_cond.notify_one();
        cars_mux.unlock();
    }
}

int main(int argc, char** argv)
{
    thread t[10];
    for(int i=0; i<10; i++)
        t[i]=thread(task);
    for(int i=0; i<10; i++)
        t[i].join();
    return 0;
}

問題是沒有輸出,似乎所有線程都被阻塞等待。

這里有兩個問題:

首先,當您構造lock對象時

unique_lock<mutex> lock(cars_mux);

然后cars_mux被鎖定。 因此,嘗試在同一線程中再次鎖定cars_mux是一個錯誤( 未定義行為 ),這是您嘗試在while循環中立即執行的操作

cars_mux.lock();

其次,線程無法加入,因為無法退出taskwhile(true)循環-汽車將永遠停泊! 您根本不需要while循環。

如果刪除第一個cars_mux.lock(); ,在while循環結束時進行的相應解鎖嘗試以及while循環本身,您應該會獲得所需的行為。

弗雷澤的答案很好,但是當我看這個時,我覺得一個可行的例子會很好。

我進行了一些更改:

  • 就個人而言,我喜歡使用RAII進行鎖定/解鎖,這樣您就不會忘記這樣做(即使這意味着額外的作用域)。 過去,我還遇到了我無法弄清的比賽條件,而改用RAII方法通常也會使這些情況消失……這很容易,所以做到了;)

  • 我喜歡看汽車何時離開,因此我也為此添加了I / O。

這是上述問題的工作代碼示例。 僅供參考,我將clang 3.1與libc ++結合使用:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using namespace std;

int cars=0;
int max_cars=5;
mutex cars_mux;
condition_variable cars_cond;

bool pred()
{
    return cars < max_cars;
}

void task()
{
    {
        unique_lock<mutex> carlock(cars_mux);
        cars_cond.wait(carlock,pred);
        cars++;
            cout << "Thread " << this_thread::get_id() 
                 << " has parked. There are " << cars << " parked cars." << endl;
    }

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

    {
        unique_lock<mutex> carlock(cars_mux);
        cars--;
        cout << "Thread " << this_thread::get_id() 
             << " has left. There are " << cars << " parked cars." << endl;
        cars_cond.notify_one();
    }
}

int main(int argc, char** argv)
{
    const int NumThreads = 10;
    thread t[NumThreads];
    for(int i=0; i<NumThreads; i++)
        t[i]=thread(task);
    for(int i=0; i<NumThreads; i++)
        t[i].join();
    return 0;
}

編輯:根據Rami Al Zuhouri的建議的簡化代碼。

暫無
暫無

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

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