2008-12-05 44 views
4

希望多次同時調用一個函數。我希望使用線程來調用一個將充分利用機器功能的函數。這是一個8核心機器,我的要求是使用機器cpu從10%到100%或更多。使用增強庫的多線程

我的要求是使用boost類。有什麼辦法可以使用boost線程或線程池來完成這個任務嗎?或者以其他方式來做到這一點?另外,如果我必須每次使用不同的參數調用多個函數(使用不同的線程),那麼執行此操作的最佳方法是什麼? [使用提升或不使用提升]以及如何?

#include <iostream> 
#include <fstream> 
#include <string.h> 
#include <time.h> 
#include <boost/thread/mutex.hpp> 
#include <boost/bind.hpp> 

using namespace std; 
using boost::mutex; 
using boost::thread; 

int threadedAPI1(); 
int threadedAPI2(); 
int threadedAPI3(); 
int threadedAPI4(); 

int threadedAPI1() { 
    cout << "Thread0" << endl; 
} 


int threadedAPI2() { 
    cout << "Thread1" << endl; 
} 

int threadedAPI3() { 
    cout << "Thread2" << endl; 
} 

int threadedAPI4() { 
    cout << "Thread3" << endl; 
} 

int main(int argc, char* argv[]) { 

    boost::threadpool::thread_pool<> threads(4); 
    // start a new thread that calls the "threadLockedAPI" function 
    threads.schedule(boost::bind(&threadedAPI1,0)); 
    threads.schedule(boost::bind(&threadedAPI2,1)); 
    threads.schedule(boost::bind(&threadedAPI3,2)); 
    threads.schedule(boost::bind(&threadedAPI4,3)); 
    // wait for the thread to finish 
    threads.wait(); 

    return 0; 
} 

以上是不工作,我不知道爲什麼? :-(

+3

它總是一個好主意,指定*如何*它是「不工作」。它不會做你想要的?它不編譯?你會得到什麼錯誤?你到底在哪裏得到它們? – jalf 2008-12-05 18:25:12

回答

6

我建議你使用功能對文檔的閱讀起來。從你在James Hopkin的回答中的評論看來,你似乎不知道boost :: bind是幹什麼的,而只是複製代碼。

boost :: bind接受一個函數(稱爲f)和可選的許多參數,並返回一個函數,該函數在調用時使用指定的參數調用f。

也就是boost::bind(threadedAPI1, 0)()(創建一個不帶參數的函數,並用參數0調用threadedAPI1(),然後調用它)相當於threadedAPI1(0)

由於您的threadedAPI函數實際上並不帶任何參數,因此您無法將任何參數傳遞給它們。這只是基本的C++。你不能調用threadedAPI1(0),但只能調用threadedAPI1(),但是當你調用該函數時,你可以嘗試(通過boost :: bind)傳遞整數0作爲參數。

所以簡單的回答你的問題是簡單地界定threadedAPI1如下:

int threadedAPI1(int i); 

然而,爲了避免了boost ::綁定一個方法調用是啓動時調用一個函數對象,而不是一個自由的功能線程。聲明一個這樣的類:

struct threadedAPI { 
    threadedAPI(int i) : i(i) {} // A constructor taking the arguments you wish to pass to the thread, and saves them in the class instance. 

    void operator()() { // The() operator is the function that is actually called when the thread starts, and because it is just a regular class member function, it can see the 'i' variable initialized by the constructor 
    cout << "Thread" << i << endl; // No need to create 4 identical functions. We can just reuse this one, and pass a different `i` each time we call it. 
    } 
private: 
    int i; 
}; 

最後,根據您的需要,普通線程可能比線程池更適合。一般來說,一個線程池只運行有限數量的線程,因此它可能會排隊某些任務,直到它的一個線程完成執行。它主要用於有許多短期任務的情況。

如果您擁有固定數量的長時間任務,則可以爲每個任務創建專用線程。

+0

謝謝,這似乎很有意義。抱歉在發佈之前不要閱讀文檔。 – gagneet 2008-12-05 18:25:32

3

如果你的興趣是在有效地使用你的處理器,那麼你可能要考慮intels線程構建塊http://www.intel.com/cd/software/products/asmo-na/eng/294797.htm。我相信它是專門設計用於利用多核心處理器,而boost線程把控制權交給用戶(即與雙核相比,TBB在四核上會有不同的線程)

至於你的代碼,你是綁定的函數,它不會將參數傳遞給一個參數,爲什麼?你可能還想檢查計劃中的返回碼

+0

謝謝帕特里克。實際上已經修改了更具體的問題。我想找到能讓我同時調用多個功能的東西。另外,我不確定如何發送參數。 – gagneet 2008-12-05 17:14:46

4

您將參數綁定到不帶參數的函數:

int threadedAPI1(); 

boost::bind(&threadedAPI1,0) 

就直接傳遞函數如果沒有參數:

threads.schedule(&threadedAPI1) 
+0

那麼做什麼是正確的方法呢? – gagneet 2008-12-05 17:48:06