簡體   English   中英

thread.join 期間出現分段錯誤

[英]Segmentation fault during thread.join

我的代碼有問題。 當我將 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 threads_finished(std::thread *threads)
{
    for (int t = 0; t < NUM_THREADS; t++)
        if (!threads[t].joinable())
            return false;
    return true;
}

有兩個原因:

  1. 如果任何線程不可連接,您將返回 false(即不,未完成),並且

  2. 您無法檢測線程是否像這樣完成。 您需要讓線程更新原子計數器/標志集或更好的由條件變量和互斥對保護的標志集,以便您可以正確地 (a) 測試線程是否完成和 (b) 等待所有線程在main()結束之前完成。

更新:

根據要求添加了參考。 建議您收藏本站。

已完成代碼執行但尚未加入的線程仍被視為活動的執行線程,因此是可加入的。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM