我正在嘗試找出多執行緒 - 我對它很陌生。我正在使用我在這里找到的 thread_pool 型別。對于足夠大的N,以下代碼段錯誤。你們能幫我理解為什么以及如何解決嗎?
#include "thread_pool.hpp"
#include <thread>
#include <iostream>
static std::mutex mtx;
void printString(const std::string &s) {
std::lock_guard lock(mtx);
std::hash<std::thread::id> tid{};
auto id = tid(std::this_thread::get_id()) % 16;
std::cout << "thread: " << id << " " << s << std::endl;
}
TEST(test, t) {
thread_pool pool(16);
int N = 1000000;
std::vector<std::string> v(N);
for (int i = 0; i < N; i ) {
v[i] = std::to_string(i);
}
for (auto &s: v) {
pool.push_task([&s]() {
printString(s);
});
}
}
這是執行緒消毒器輸出(注意 ===> 注釋,我將您引導到適當的行”):
SEGV on unknown address 0x000117fbdee8 (pc 0x000102fa35b6 bp 0x7e8000186b50 sp 0x7e8000186b30 T257195)
0x102fa35b6 std::basic_string::__get_short_size const string:1514
0x102fa3321 std::basic_string::size const string:970
0x102f939e6 std::operator<<<…> ostream:1056
0x102f9380b printString RoadRunnerMapTests.cpp:37 // ==> this line: void printString(const std::string &s) {
0x102fabbd5 $_0::operator() const RoadRunnerMapTests.cpp:49 // ===> this line: v[i] = std::to_string(i);
0x102fabb3d (test_cxx_api_RoadRunnerMapTests:x86_64 0x10001eb3d) type_traits:3694
0x102fabaad std::__invoke_void_return_wrapper::__call<…> __functional_base:348
0x102faba5d std::__function::__alloc_func::operator() functional:1558
0x102fa9669 std::__function::__func::operator() functional:1732
0x102f9d383 std::__function::__value_func::operator() const functional:1885
0x102f9c055 std::function::operator() const functional:2560
0x102f9bc29 thread_pool::worker thread_pool.hpp:389 // ==> [this](https://github.com/bshoshany/thread-pool/blob/master/thread_pool.hpp#L389) line
0x102fa00bc (test_cxx_api_RoadRunnerMapTests:x86_64 0x1000130bc) type_traits:3635
0x102f9ff1e std::__thread_execute<…> thread:286
0x102f9f005 std::__thread_proxy<…> thread:297
0x1033e9a2c __tsan_thread_start_func
0x7fff204828fb _pthread_start
0x7fff2047e442 thread_start
uj5u.com熱心網友回復:
解構式的呼叫順序與變數宣告順序相反。iev將早于 被銷毀pool,因此當池中的某些執行緒將呼叫 to 時printString(),引數字串將不是有效物件,因為v它的內容已經被銷毀。為了解決這個問題,我建議v在pool.
uj5u.com熱心網友回復:
傳遞給執行緒池的任務包含對 vector 內容的參考v,但是在池留下帶有懸空參考的任務之前,此向量超出范圍。為了解決這個問題,您需要重新排序變數的范圍:
int N = 1000000;
std::vector<std::string> v(N);
thread_pool pool(16);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382691.html
