C++ 线程不是在Linux上终止,而是在Mac上终止

C++ 线程不是在Linux上终止,而是在Mac上终止,c++,linux,multithreading,boost,C++,Linux,Multithreading,Boost,我目前正在研究一种遗传算法,其中一个新的种群是用不同的独立线程计算的。我的程序在OSX上运行良好,但有些线程不会在Linux机器上终止 我有以下方法,每个线程都会执行,直到生成足够多的个体。我使用的是一个互斥锁,它是population类的一部分,就像这个方法一样。因此互斥对象不是静态的。该方法将传递一组父对象,它可以在第一个父对象上选择一个父对象来生成新的子对象。子对象是由另一个父对象通过突变或重组产生的。在随机选择和布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔

我目前正在研究一种遗传算法,其中一个新的种群是用不同的独立线程计算的。我的程序在OSX上运行良好,但有些线程不会在Linux机器上终止

我有以下方法,每个线程都会执行,直到生成足够多的个体。我使用的是一个互斥锁,它是population类的一部分,就像这个方法一样。因此互斥对象不是静态的。该方法将传递一组父对象,它可以在第一个父对象上选择一个父对象来生成新的子对象。子对象是由另一个父对象通过突变或重组产生的。在随机选择和布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔布尔

我在互联网上搜索了线程不会终止的原因,并在使用std::random_设备或std::mt19937对象的方法周围添加了一些可能不必要的锁

我的程序的输出跳过了线程正常工作的部分:

0 started
2 started
3 started
3 entered while
0 entered while
1 started
2 entered while
1 entered while
3 got male 1
0 got male 0
3 got female
2 got male 1
1 got male 1
2 got female
1 got female
0 got mutated
0 before is valid
0 inserting
0 inserted
0 updating size
0 updating size about to lock
0 updating size about to locked
0 returning
Thread finished10
2 got combined
2 before is valid
2 inserting
2 inserted
2 updating size
2 updating size about to lock
2 updating size about to locked
2 returning

在这之后,我没有得到任何额外的输出。对我来说,锁防护似乎无法释放互斥锁。这是我连接线程的顺序吗?因为我尝试在线程2之前加入线程1,即使它还没有完成?

在代码中我不喜欢的一件事是误用锁。例如,当您检索容器的大小时,您无法确保刚检索到的大小在解锁互斥锁之后是正确的。因此,正确的模式可能是锁定代码块,在该代码块中检索大小,并在假设该大小正确的情况下使用容器,然后在不再需要该容器时解锁它

因此,您应该重新编写代码,因为在许多地方可能存在竞争条件。您的问题有一个可能的答案,请查看以下代码:

    mutex.lock();
    individual male = *utilities::container::select_randomly(parents.begin(), selectable_parents_end);
    bool generate_child = utilities::container::bool_with_prob(0.3);
    mutex.unlock();

在select_中随机抛出的异常是什么?您永远不会解锁互斥锁,这是一种死锁情况。为什么它会抛出异常?例如,因为可选值\u parents\u end因争用条件而过时。

首先要做的是找出线程的位置。他们是在某条特定路线上受阻,还是在前进,但却陷入了某种无休止的循环?您可以使用调试器,或者通过添加一些临时printf并查看哪些内容可以打印,哪些不可以打印来解决这个问题。一旦你知道线程被卡在哪里,你就可以开始思考为什么它们会被卡在那里。当你给我们一个答案时,这将很容易。这很接近,但请完成。我用一些额外的输出更新了我的问题。谢谢大家的评论!仍然不是一个好消息。这不是一个程序。请单击提供的链接并阅读说明。在示例中,没有输出3的代码。例如,在检索容器大小之前,如果您只需要它的大小[需要引用],则不需要锁定。没有标准容器是线程安全的。不管你用它们做什么,好吧,我同意容器不是线程安全的,但我的观点是:当你开始使用它时,你得到的值不是真的。这比仅仅选择一个随机值要好一点。我不会对你的答案的其余部分进行评论,但是关于你不需要锁来读取容器大小的建议是完全错误的,而且相当危险。不仅是int或std::size_ts,或者其他非原子的东西,而且假设实现细节。代码符合规范,而不是关于实现的假设。我发现了问题。你的回答帮助很大。我在一个函数中没有得到异常,但我同时从两个线程访问了一些I/O。这引起了一些奇怪的行为。
std::cout << i << " updating size" << std::endl;

{
    std::cout << i << " updating size about to lock" << std::endl;
    boost::lock_guard<boost::mutex> lock(configuration::mutex);

    std::cout << i << " updating size about to locked" << std::endl;

    individuals_size = individuals.size();

    if(individuals_size >= size)
    {
        std::cout << i << " returning" << std::endl;
        return;
    }
}
0 started
2 started
3 started
3 entered while
0 entered while
1 started
2 entered while
1 entered while
3 got male 1
0 got male 0
3 got female
2 got male 1
1 got male 1
2 got female
1 got female
0 got mutated
0 before is valid
0 inserting
0 inserted
0 updating size
0 updating size about to lock
0 updating size about to locked
0 returning
Thread finished10
2 got combined
2 before is valid
2 inserting
2 inserted
2 updating size
2 updating size about to lock
2 updating size about to locked
2 returning
    mutex.lock();
    individual male = *utilities::container::select_randomly(parents.begin(), selectable_parents_end);
    bool generate_child = utilities::container::bool_with_prob(0.3);
    mutex.unlock();