簡體   English   中英

使用 std::thread 的奇怪 `joinable()` 行為

[英]Strange `joinable()` behavior with std::thread

我正在嘗試實現一個線程列表,其中一個線程通過std::thread::join與下一個線程通信,直到所有作業都完成為止。

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <sstream>
#include <stdio.h>

std::vector<std::thread> workers;

void f1(void)
{
  std::cout<<"begin f1"<<std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::cout<<"end f1"<<std::endl;
}

void f2(int sleep_for, std::thread & previous_thread)
{
  try
  {
    previous_thread.join();
    std::cout<<"begin f2"<<std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout<<"end f2"<<std::endl;
  }
  catch (const std::system_error& ex)
  {
    std::stringstream ss;
    ss << ex.code() << '\n';
    ss << ex.code().message() << '\n';
    ss << ex.what() << '\n';
    printf("%s",ss.str().c_str());
  }
}

int main(void)
{
  std::cout<<0<<std::endl;
  workers.emplace_back(&f1);
  for(int i=0;i<3;i++)
  {
    std::cout<<i+1<<std::endl;
    workers.emplace_back(&f2, i, std::ref(workers.back()));
  }
  workers.back().join();
  /*
  std::thread t(&f1);
  std::thread t1(&f2, 0, std::ref(t));
  std::thread t2(&f2, 1, std::ref(t1));                                                                                                                                                                                                        
  std::thread t3(&f2, 2, std::ref(t2));
  t3.join();
  */
  return 0;
}

在這段代碼中,您可以看到我正在啟動 4 個線程,第一個線程之后的每個線程都應該join前一個線程,以便等待它完成。 但是,我收到錯誤 22s(無效參數),根據文檔,這意味着在某些情況下joinable()是錯誤的。

有時執行確實使它通過了所有線程,但隨后在~thread中拋出異常,導致程序在退出之前崩潰。

我在這里做錯了什么? 文檔在這方面非常直接,所以我不確定我錯過了什么

編輯:我標記為正確的答案確實指出了代碼的問題,但我選擇的解決方案是使用std::list而不是std::vector

workers.emplace_back(&f2, i, std::ref(workers.back()));

這會導致 UB,因為您將指針傳遞給工作人員的數據,然后增加它的大小,這可能會重新分配其所有成員,從而導致引用無效。

暫無
暫無

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

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