2014-02-27 66 views
1

我正在學習如何在Boost庫使用線程,我的搜索過程中,我發現下面的代碼:void運算符()()瞭解

struct count 
{ 
    count(int id) : id(id) {} 

    void operator()() 
    { 
     for (int i = 0; i < 10; ++i) 
     { 
      boost::mutex::scoped_lock 
      lock(io_mutex); 
      std::cout << id << ": " << i << std::endl; 
     } 
    } 
    int id; 
}; 

int main(int argc, char* argv[]) 
{ 
    boost::thread thrd1(count(1)); 
    boost::thread thrd2(count(2)); 

    thrd1.join(); 
    thrd2.join(); 
    return 0; 
} 

這個程序工作正常,但我的問題是,什麼是void operator()()函數的行爲?因爲有兩個線程,每個線程都使用不同的值初始化計數。這是兩個主要的count變量是單獨創建的,所以他們的void operator()()應該是不同的每個變量。但似乎void operator()()是兩個線程相同。在這個代碼void operator()()還有一件事是不是從任何地方被調用,所以它如何運行?

有人能解釋一下這個函數裏面發生了什麼嗎?

void operator()() 
+0

是什麼讓你覺得它們對於兩個線程都是一樣的? –

+0

@JosephMansfield我運行這個程序檢查互斥鎖的工作情況,它顯示了互斥鎖的確切工作情況。它不允許其他線程在第一個線程完成之前處理此函數。 – nabeel

回答

4

這是一個棘手的語法。

boost::thread thrd1(count(1)); 
boost::thread thrd2(count(2)); 

在這些兩行,operator()NOT直接調用。這裏可見的count(n)構造函數。然後,將用'1'和'2'值構造的對象傳遞給thread對象,然後內部調用operator()在爲此目的創建的不同線程上運行特定任務。

但是由於兩個對象在它們的記憶中記住了不同的值(1/2),因此operator()中的通用代碼在不同的實際值id字段上操作。這就是爲什麼操作員沒有參數:所有必需的參數在構造過程中都存儲在「count」對象中。

Btw。構造一個對象,並調用operator(),線是這樣的:

count(1)(); 
+0

@JosephMansfield:謝謝,我已經自動粘貼了op-definition,而沒有想到。 – quetzalcoatl

+0

但爲什麼它在內部調用運算符函數?意思是如果我定義了一些其他功能,它將不會以相同的方式運行。 – nabeel

+1

當你開始一個新的線程時(例如'boost :: thread'類),「線程」必須知道你想要的任務/任務/代碼在該線程上運行。你**有**告訴它你想做什麼_somehow_。而「告訴的方式」必須足夠普遍,以便你能夠給它任何你想要的工作。因此,'boost :: thread' _requires_你需要把這個工作放到一個operator()中。如果你遵守它,那麼'boost :: thread'就可以簡單地接受任何你給予的對象(例如「count」對象),創建線程,運行着名的operator()來形成你的對象,並且確保這個工作將被完成 – quetzalcoatl

0

操作者在C++超載的語法是:

返回型操作者操作者名稱(參數); 示例:int運算符+(int其他) 此處的運算符名稱爲「+」。在你的情況下,它是「()」

現在在這裏,你有2個線程實例,每個實例都有自己的count實例。當線程調用operator()()時,它會讀取特定線程實例的計數值,這就是爲什麼您對同一個運算符有不同結果的原因。

0

它肯定會幫助您閱讀代碼的上下文在這裏爲其他讀者發佈一個鏈接:))。

沒有任何其他上下文來幫助我,我猜這是一個演示boost :: thread的新學習者。我會假設你知道線程是如何工作的 - 如果你是新手,this link是一個很好的初學者概念參考。

進行分解:

boost::thread thrd1(count(1)); 
    boost::thread thrd2(count(2)); 

創建兩個線程用不同的ID。正如@quetzalcoatl所提到的,boost線程接受一個函數對象,該對象定義了operator()()並在不同的線程中執行該運算符的內容。這意味着我們現在有3個線程 - 主執行線程和上面創建的2個線程。

thrd1.join(); 
    thrd2.join(); 

其他兩個線程主執行線程等待加入 - 即完成他們的處理,並指示主線程,他們就完成了。當他們加入時,線程被終止(請注意,thrd1是一個boost線程對象 - 用於引用我們在幕後創建的實際線程,並且一直可用,直到棧結束)。

operator()()是一種監視方法。哪個線程正在運行和b。有多少'skipping-between-threads'發生。在解釋之前,讓我們看看結果。它很可能是這樣的(但可能不完全):

1: 0 
1: 1 
2: 0 
2: 1 
2: 2 
2: 3 
1: 2 ...  

所以程序(在這種情況下)運行的線程#1兩個循環,切換到線#2,運行了幾個圈,又回到了#1並繼續運行。 There is a reason兩個線程都不能同時進入循環 - boost scoped_lock抓住(外部)io_mutex,將其鎖定以供該線程使用,並繼續運行,直到scoped_lock對象被銷燬並釋放io_mutex對象。這意味着,雖然兩個線程並行運行,但在「scoped_lock」調用後,只有一個對象可以訪問該特定堆棧。

希望有所幫助。