我是C ++中多线程的完全新手,并决定从Boost Libraries开始。另外,我在Vista上使用英特尔的C ++编译器(来自Parallel Studio 2011)和VS2010。
我正在对遗传算法进行编码,并希望利用多线程的好处:我想为群体中的每个个体(对象)创建一个线程,以便他们计算它们的适应性(繁重的操作)并行地减少总执行时间。
据我了解,每当我启动一个子线程时,它就会“在后台”工作,并且父线程继续执行下一条指令,对吗?所以,我想创建并启动我需要的所有子线程(在for
循环中),然后等待它们完成(在另一个join()
循环中调用每个线程的for
)在继续之前。
我面临的问题是第一个循环不会继续下一次迭代,直到新创建的线程完成工作。然后,第二个循环就像去了一样好,因为所有的线程都已经被循环命中时加入。
以下是(我认为是)相关的代码片段。告诉我你还有什么需要知道的。
class Poblacion {
// Constructors, destructor and other members
// ...
list<Individuo> _individuos;
void generaInicial() { // This method sets up the initial population.
int i;
// First loop
for(i = 0; i < _tamano_total; i++) {
Individuo nuevo(true);
nuevo.Start(); // Create and launch new thread
_individuos.push_back(nuevo);
}
// Second loop
list<Individuo>::iterator it;
for(it = _individuos.begin(); it != _individuos.end(); it++) {
it->Join();
}
_individuos.sort();
}
};
并且,线程对象个性化:
class Individuo {
private:
// Other private members
// ...
boost::thread _hilo;
public:
// Other public members
// ...
void Start() {
_hilo = boost::thread(&Individuo::Run, this);
}
void Run() {
// These methods operate with/on each instance's own attributes,
// so they *can't* be static
generaHoc();
calculaAptitud();
borraArchivos();
}
void Join() {
if(_hilo.joinable()) _hilo.join();
}
};
谢谢! :D
答案 0 :(得分:7)
如果这是你的真实代码,那么你就有问题了。
for(i = 0; i < _tamano_total; i++) {
Individuo nuevo(true);
nuevo.Start(); // Create and launch new thread
_individuos.push_back(nuevo);
}
void Start() {
_hilo = boost::thread(&Individuo::Run, this);
}
此代码在堆栈上创建一个新的Individuo
对象,然后启动一个运行的线程,将该堆栈对象的this
指针传递给新线程。然后将复制该对象放入list
,立即销毁堆栈对象,在新线程中留下悬空指针。这会给你未定义的行为。
由于list
一旦插入后就永远不会移动内存中的对象,你可以在插入列表后启动线程:
for(i = 0; i < _tamano_total; i++) {
_individuos.push_back(Individuo(true)); // add new entry to list
_individuos.back().Start(); // start a thread for that entry
}