簡體   English   中英

使用 C++ 中的線程向量創建隊列時出現 Segfault

[英]Getting Segfault while Creating a Queue using Vector of Threads in C++

我在使用線程向量創建隊列時遇到分段錯誤:11,請您幫我解決。

#include <thread>
#include <queue>
#include <iostream>
using namespace std;

int tcount = 0;

template <typename T>
void thread_spawn_q(queue<T> &q)
{
    vector<thread> ths;
    for (int i = 1; i <= 20000; i++)
    {
        ths.push_back(thread(static_cast<void (queue<T>::*)(T &&)>(&queue<T>::push), &q, to_string(i)));
        ++tcount;
    }
    for (auto &th : ths)
    {
        th.join();
    }
}
int main()
{
    queue<string> q = queue<string>();
    thread_spawn_q(q);
    cout << "tcount:" << tcount << endl;
    return 0;
}

編輯#1

只制作5 個線程而不是20000個。 我仍然間歇性地收到 Segfault 並且還有錯誤:未分配被釋放的指針。

cpptest$./sof_test2.exec

噸數:5

cpptest$./sof_test2.exec

噸數:5

sof_test2.exec(77351,0x11944be00) malloc: *** object 錯誤 0x100000010: 未分配指針被釋放

sof_test2.exec(77351,0x11944be00) malloc: *** 在 malloc_error_break 中設置斷點進行調試

中止陷阱:6

cpptest$./sof_test2.exec

噸數:5

cpptest$./sof_test2.exec

噸數:5

sof_test2.exec(77358,0x10dbd9e00) malloc: *** object 錯誤 0x2000000000000: 指針被釋放未分配

sof_test2.exec(77358,0x10dbd9e00) malloc: *** 在 malloc_error_break 中設置斷點進行調試

中止陷阱:6

cpptest$./sof_test2.exec

噸數:5

cpptest$./sof_test2.exec

分段錯誤:11

cpptest$./sof_test2.exec

噸數:5

sof_test2.exec(77368,0x10f1f7e00) malloc: *** object 錯誤 0x100007fcb4c405dc: 未分配指針

sof_test2.exec(77368,0x10f1f7e00) malloc: *** 在 malloc_error_break 中設置斷點進行調試

中止陷阱:6

正如@273K 所說:“標准容器不是線程安全的”:您需要使用互斥鎖進行同步,如下所示:

#include <iostream>
#include <mutex>
#include <queue>
#include <thread>

int tcount{0};

template <typename T>
void thread_spawn_q(std::queue<T> &q)
{
    std::vector<std::thread> ths;
    std::mutex mutex;
    for (int i = 1; i <= 5; i++)
    {
        // Your version: ths.push_back(thread(static_cast<void (queue<T>::*)(T &&)>(&queue<T>::push), &q, to_string(i)));
        /* Easier-to-read version of same:
        ths.push_back(std::thread(
            [&q](int i) {
                q.push(std::to_string(i));
            },
            i));*/
        // Correct version, using a mutex
        ths.push_back(std::thread(
            [&q, &mutex](int i) {
                // We still call std::to_string in parallel...
                auto s = std::to_string(i);
                std::unique_lock lock{mutex};
                // ... but only one thread at a time is looking at q while it's being modified:
                q.push(std::move(s));
            },
            i));
        ++tcount;
    }
    for (auto &th : ths)
    {
        th.join();
    }
}
int main()
{
    auto q = std::queue<std::string>();
    thread_spawn_q(q);
    std::cout << "tcount:" << tcount << std::endl;
    return 0;
}

https://godbolt.org/z/KzWKqsz9n

暫無
暫無

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

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