我的代码有问题。当我将argv [1]增加到4.294.967.295(INT_MAX)时我得到了一个分段错误,尽管我选择了long long int'作为数据类型:
#define NUM_THREADS 5
// ...
int main (int argc, char **argv)
{
// allocating memory and declaring threads
std::thread thread[NUM_THREADS];
bool *sv_ptr = (bool *) calloc(atoll(argv[1]), sizeof(bool));
short int t = 0;
long long int i = 2;
// initialize threads
for (t = 0; t < NUM_THREADS; t++, i++)
thread[t] = std::thread(remove_multiples, i, sv_ptr, atoll(argv[1]));
t = 0;
while (i < atoll(argv[1]) || !threads_finished(thread))
{
if (sv_ptr[i] || thread[t].joinable())
{
// starting new tasks
if (thread[t].joinable())
{
thread[t].join(); // <- segfault occurs here
thread[t] = std::thread(remove_multiples, i, sv_ptr, atoll(argv[1]));
}
// printing results
if (!sv_ptr[i-NUM_THREADS])
std::cout << (i - NUM_THREADS) << std::endl;
i++;
}
// increment thread iterator
t = (t + 1) % NUM_THREADS;
}
// ...
}
void remove_multiples(long long int n, bool *sv_ptr, long long int max)
{
for (int i = 2; i*n < max; i++)
sv_ptr[i*n] = true;
}
bool threads_finished(std::thread *threads)
{
for (int t = 0; t < NUM_THREADS; t++)
if (!threads[t].joinable())
return false;
return true;
}
加入可连接线程时发生分段错误。
感谢您的帮助!
编辑:我想在我的16 GB机器上测试堆分配,因此我编写了这个程序。我能够创建一个大约1.5万亿个bool的数组,之前我用一个单线程程序做了这个。 分配时不会发生错误!我有足够的记忆力。它出现在线程管理中的某处
答案 0 :(得分:1)
好吧我在调试器中运行了这段代码(在重新安排函数顺序并添加缺少的包含文件以便编译之后)。
对我来说,段错误发生在程序结束时。我强烈怀疑这个函数中的逻辑是不正确的:
bool threads_finished(std::thread *threads)
{
for (int t = 0; t < NUM_THREADS; t++)
if (!threads[t].joinable())
return false;
return true;
}
有两个原因:
如果任何线程不可加入,你将返回false(即,no,not finished),
您无法检测线程是否已完成此操作。您需要获取线程来更新原子计数器/标志集或更好,由条件变量和互斥量对保护的标志集,以便您可以正确地(a)测试线程是否完整以及(b)等待所有线程在main()
结束之前完成。
更新:
根据要求添加了参考。建议您将此网站加入书签。
已完成执行代码但尚未加入的线程仍被视为活动执行线程,因此可以加入。