thread.join

时间:2015-10-19 17:36:04

标签: c++ multithreading c++11

我的代码有问题。当我将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的数组,之前我用一个单线程程序做了这个。 分配时不会发生错误!我有足够的记忆力。它出现在线程管理中的某处

1 个答案:

答案 0 :(得分:1)

好吧我在调试器中运行了这段代码(在重新安排函数顺序并添加缺少的包含文件以便编译之后)。

对我来说,段错误发生在程序结束时。我强烈怀疑这个函数中的逻辑是不正确的:

bool threads_finished(std::thread *threads)
{
    for (int t = 0; t < NUM_THREADS; t++)
        if (!threads[t].joinable())
            return false;
    return true;
}

有两个原因:

  1. 如果任何线程不可加入,你将返回false(即,no,not finished),

  2. 您无法检测线程是否已完成此操作。您需要获取线程来更新原子计数器/标志集或更好,由条件变量和互斥量对保护的标志集,以便您可以正确地(a)测试线程是否完整以及(b)等待所有线程在main()结束之前完成。

  3. 更新:

    根据要求添加了参考。建议您将此网站加入书签。

      

    已完成执行代码但尚未加入的线程仍被视为活动执行线程,因此可以加入。

    http://en.cppreference.com/w/cpp/thread/thread/joinable