簡體   English   中英

C ++的遞歸線程使資源暫時不可用

[英]recursive threading with C++ gives a Resource temporarily unavailable

所以我試圖創建一個程序,該程序實現一個函數,該函數生成一個隨機數(n),並基於n創建n個線程。 主線程負責打印最小和最大的葉子。 主線程的層次結構深度為3。

我寫了下面的代碼:

#include <iostream>
#include <thread>
#include <time.h>
#include <string>
#include <sstream>

using namespace std;


// a structure to keep the needed information of each thread
struct ThreadInfo
{
    long randomN;
    int level;
    bool run;
    int maxOfVals;
    double minOfVals;
};


// The start address (function) of the threads
void ChildWork(void* a) {

    ThreadInfo* info = (ThreadInfo*)a;

    // Generate random value n
    srand(time(NULL));
    double n=rand()%6+1;


    // initialize the thread info with n value
    info->randomN=n;
    info->maxOfVals=n;
    info->minOfVals=n;


    // the depth of recursion should not be more than 3
    if(info->level > 3)
    {
        info->run = false;
    }

    // Create n threads and run them
    ThreadInfo* childInfo = new ThreadInfo[(int)n];
    for(int i = 0; i < n; i++)
    {
        childInfo[i].level = info->level + 1;
        childInfo[i].run = true;
        std::thread tt(ChildWork, &childInfo[i]) ;
        tt.detach();
    }


    // checks if any child threads are working
    bool anyRun = true;
    while(anyRun)
    {
        anyRun = false;
        for(int i = 0; i < n; i++)
        {
            anyRun = anyRun || childInfo[i].run;
        }
    }

    // once all child threads are done, we find their max and min value
    double maximum=1, minimum=6;
    for( int i=0;i<n;i++)
    {
    //  cout<<childInfo[i].maxOfVals<<endl;


        if(childInfo[i].maxOfVals>=maximum)
            maximum=childInfo[i].maxOfVals;

        if(childInfo[i].minOfVals< minimum)
            minimum=childInfo[i].minOfVals;

    }

    info->maxOfVals=maximum;
    info->minOfVals=minimum;


    // we set the info->run value to false, so that the parrent thread of this thread will know that it is done
    info->run = false;

}

int main()
{
    ThreadInfo info;


    srand(time(NULL));
    double n=rand()%6+1;

    cout<<"n is: "<<n<<endl;

    // initializing thread info
    info.randomN=n;
    info.maxOfVals=n;
    info.minOfVals=n;
    info.level = 1;
    info.run = true;

   std::thread t(ChildWork, &info) ;
     t.join();

    while(info.run);

    info.maxOfVals= max<unsigned long>(info.randomN,info.maxOfVals);
    info.minOfVals= min<unsigned long>(info.randomN,info.minOfVals);

    cout << "Max is: " << info.maxOfVals <<" and Min is: "<<info.minOfVals;

}

代碼編譯沒有錯誤,但是當我執行它時,它給出了以下信息:

libc ++ abi.dylib:以類型為std :: __ 1 :: system_error的未捕獲異常終止:線程構造函數失敗:資源暫時不可用中止陷阱:6

您產生了太多線程。 它看起來有點像fork()炸彈。 線程是非常重的系統資源。 謹慎使用它們。

在函數void Childwork我看到兩個錯誤:

  1. 正如有人已經在注釋中指出的那樣,您檢查線程的信息級別,然后繼續創建更多線程,而不管先前的檢查如何。

  2. 在產生新線程的for循環中,在產生實際線程之前立即增加信息級別。 但是,您可以在此處增加一個新創建的ThreadInfo實例ThreadInfo* childInfo = new ThreadInfo[(int)n] childInfo中的所有實例的級別均為0。基本上,您產生的每個線程的級別為1。

通常,避免使用線程來實現I / O綁定操作(*)的並發性。 只需使用線程即可為獨立的CPU綁定操作實現並發性。 根據經驗,您所需要的線程數永遠不會超過系統中具有CPU內核(**)的線程數。 擁有更多內容不會提高並發性,也不會提高性能。

(*)您應始終使用直接函數調用和基於事件的系統來運行偽並發I / O操作。 您不需要任何線程來執行此操作。 例如,TCP服務器不需要任何線程即可為數千個客戶端提供服務。

(**)這是理想的情況。 實際上,您的軟件由獨立開發人員開發並由不同模式維護的多個部分組成,因此可以從理論上避免一些線程。

多線程在2019年仍然是火箭科學。尤其是在C ++中。 除非您確切知道自己在做什么,否則不要這樣做。 這是一系列處理線程的博客文章

暫無
暫無

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

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