0
我正在嘗試使用boost線程創建一個簡單的多線程應用程序。基本上我必須計算大約100件事情,並且希望一次將它分成8個線程。唯一棘手的方面是我需要傳遞一個指針給worker,然後得到一些返回值。在下面的例子中,指針只是一個浮點數,但在我的實際應用中,它是一個更大的類。這段錯誤。我究竟做錯了什麼?boost線程:被釋放後被修改的對象
編輯寫作爲一個獨立的文件:
#include <iostream>
#include <vector>
#include <boost/thread.hpp>
using namespace std;
class Worker {
public:
Worker(boost::atomic<int> & threads,
boost::mutex & mutex,
boost::condition_variable & condition):
threads_(threads), mutex_(mutex), condition_(condition){}
void do_stuff(int num, float * num2){
results_.reserve(num);
for (int i=0;i<num;i++){
results_.push_back(*num2);
}
boost::mutex::scoped_lock lock(mutex_);
threads_--;
condition_.notify_one();
}
std::vector<float> results_;
private:
boost::atomic<int> & threads_;
boost::mutex & mutex_;
boost::condition_variable & condition_;
};
int main(){
int ntasks = 25;
std::vector<Worker> workers;
workers.reserve(ntasks);
boost::thread_group thread_group;
boost::mutex mutex;
boost::condition_variable condition;
boost::atomic<int> threads(0);
float * bean;
*bean = 3.14159;
for(int iz=0;iz<ntasks;iz++){
boost::mutex::scoped_lock lock(mutex);
while (threads >= 8) condition.wait(lock);
Worker w = Worker(threads, mutex, condition);
workers.push_back(w);
boost::function<void()> th_func = boost::bind(&Worker::do_stuff,
&workers.back(),5,bean);
boost::thread * thread = new boost::thread(th_func);
thread_group.add_thread(thread);
threads++;
}
thread_group.join_all();
//inspect the results
for (int iw=0;iw<workers.size();iw++){
for (int it=0;it<5;it++){
cout<<workers[iw].results_[it]<<" ";
}
cout<<endl;
}
return 0;
}
在我的Mac編譯:
g++ test.cpp -o thread -I/usr/local/include -L/usr/local/lib -lboost_thread-mt -lboost_system-mt
對於這樣的問題,請隨時發佈[MCVE] –
當你通過'&w'新的線程,它超出範圍在目前結束的迭代。你應該傳遞一個對象的副本或者在新線程運行時不會超出範圍的變量的地址,例如在保留足夠的空間後傳遞&workers.back(),以便稍後push_back調用不會重新分配工人內部的數組。另外,在讀取它們之前,您需要等待線程完成寫入結果,方法是銷燬thread_group或其他內容。 – programmerjake
如果你在linux上,我建議使用valgrind和helgrind工具,它會發現線程同步問題。 – programmerjake