簡體   English   中英

在C ++中創建標准線程會使程序崩潰

[英]Creating std threads in C++ crashes the program

每當我使用線程執行以下代碼時,程序都會出現此錯誤:

調試錯誤! 程序:... /path/to/.exe

已調用abort()

我想創建一個調用成員函數的線程。 這是我正在使用的功能:

void ServerVote::createConnexionThreads()
{
    for (int i = 0; i <= 50; ++i)
    {
        m_connexionThreads.push_back(&(std::thread(&ServerVote::acceptConnection,*this, i)));
    }
    for (int i = 0; i <= 50; ++i)
    {
        m_connexionThreads[i]->join();
    }
}

如果需要,我可以提供其他代碼。 使用調試器時,我發現該程序在創建第一個線程之后,在push_back線程之后立即崩潰。 然后調用〜thread(),它在該函數內部崩潰。 這是向量聲明:

std::vector<std::thread*> m_connexionThreads;

我正在使用Visual Studio2015。acceptConnection函數內部具有while(true),並計划在以后終止。

編輯:

感謝您的回答,但是使用線程對象而不是指針時無法編譯。 因此,當我嘗試推入此向量時:

std::vector<std::thread> m_connexionThreads;

for (int i = 0; i <= 50; ++i)
{
        m_connexionThreads.push_back((std::thread(&ServerVote::acceptConnection,*this, i)));
}

編譯時出現此錯誤:

error C2280: 'std::thread::thread(const std::thread &)': attempting to reference a deleted function

您不應在任何情況下嘗試使用臨時地址。 實際上,這是MSVC中的一個錯誤,該錯誤允許此代碼。 任何符合標准的編譯器都會在此處產生錯誤。

相反,您應該使用這樣的線程對象(請參閱代碼下方的編輯,以了解為什么會這樣):

#include <thread>
#include <vector>

void acceptConnection(int);

void foo() {
  std::vector<std::thread> vec;
  for (int i = 0; i <= 50; ++i)
        vec.push_back(std::thread(acceptConnection, i));
}

為什么使用這種方法優於使用分配給線程對象的指針? 有很多好處:

  1. 它減少了打字-即使沒有其他事情,所有事物都是平等的(盡管它們不是!),打字少勝於打字。
  2. 使用指針時要格外小心。 例如,您不應將原始指針用作矢量數據類型,而應使用unique_ptr以確保自動進行內存清理-這使語法更加難看!
  3. 使用動態分配的內存會拖累性能。 您被擊中兩次-第一次分配內存,第二次釋放內存。 為什么要遭受這種懲罰?

您正在堆棧中創建線程的本地實例,獲取其地址並將其推入向量。 線程對象將在方法退出時被刪除,因此您將獲得指向已刪除對象的指針。

您應該使用new在堆中創建線程對象,這樣它就不會在方法退出時被刪除,或者不使用指向線程對象的指針。

暫無
暫無

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

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