簡體   English   中英

使用和加入來自不同線程的std :: thread對象

[英]Using and joining a std::thread object from different threads

這是一個基於傳遞給我的代碼的最小示例:

// Example program
#include <iostream>
#include <string>
#include <thread>


int main()
{
  std::cout << "Start main\n";
  int i = 0;
  auto some_thread = std::thread([&]() { 
     std::cout << "Start some thread\n";
      while(i++ < 100) {
        std::cout << i << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      }
  });
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));  

  auto some_thread2 = std::thread([&]() { 
      std::cout << "Start thread 2\n";
      if (some_thread.joinable()) {
        std::cout << "Thread 2 will join\n";
        some_thread.join();
        std::cout << "Thread 2 ended\n";
      } else {
        std::cout << "Thread 2 ended but didn't join\n";
      }
  });
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  if (some_thread.joinable()) {
    std::cout << "Main will join\n";
    some_thread.join();
    std::cout << "Main ended\n";
    return 0;
  } else {
    std::cout << "Main ended but didn't join\n";
    return 1;
  }
}

簡而言之,完整程序(如本例中所示)從不同的線程訪問某些std::thread對象,並嘗試將其joindetach

我知道這是一個糟糕的設計,並且如果您嘗試兩次加入一個線程,它將崩潰,因為在第一個線程完成之后,便沒有與之關聯的線程。 但這種情況並非如此。

在此示例中,它在線程結束之前崩潰並且帶有Abort trap:6 它只是打印幾個數字,然后崩潰(線程不會結束其執行)。

代碼不是我的,我也不想重新設計。 我只是想了解為什么它崩潰了。

最后一點,原始代碼在某種程度上使用了信號量之類的代碼(盡管有一些隨機崩潰)。

我知道...如果您嘗試加入一個線程兩次,它將崩潰,因為在第一個線程完成之后,便沒有與之關聯的線程。 但這種情況並非如此。

相反,這就是這里正在發生的事情。 some_thread2調用some_thread.join()並且在等待some_thread退出時,主線程也在調用some_thread.join() some_thread仍處於活動狀態,並且在兩次檢查時尚未聯接,因此joinable()在兩種情況下均返回true。

避免崩潰的一種方法是添加some_thread2.join(); 在主線程中檢查some_thread.joinable()之前(但是,如果這樣做,則主線程無需加入some_thread )。

無論如何,不​​清楚為什么要從兩個不同的線程中join線程,因此很難提出更好的解決方案。

std :: thread庫通常在支持pthread的環境中(例如:libstdc ++)在pthread之上實現。

引用pthread_join linux 文檔

如果多個線程同時嘗試加入同一線程,則結果是不確定的。

它還提到它返回以下錯誤:

EINVAL另一個線程已經在等待與此線程的加入。

暫無
暫無

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

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