主頁 > 軟體工程 > c -如何將值從父執行緒或子執行緒中的子執行緒下的值傳遞給C

c -如何將值從父執行緒或子執行緒中的子執行緒下的值傳遞給C

2021-11-06 17:19:29 軟體工程

我有一個具有以下值的 file.txt:1234 567 8910

我想用 C 創建一個程式,它創建 x 個子執行緒,其中 x 是“file.txt”中的行數。子執行緒接收該行,因此它將該行拆分為數字并將它們存盤在一個陣列中。

然后我想在每個子執行緒下創建 y 個孫子執行緒,y 是該子執行緒陣列中的位數或接收到的行值,并將每個孫子執行緒傳遞一個數字。

比如上面的file.txt,我在main()中的父執行緒會創建3個子執行緒。第一個子執行緒將收到“1234”,第二個“567”,第三個“8910”。然后第一個子執行緒將創建 4 個孫子執行緒并傳遞第一個孫子執行緒“1”、第二個“2”、第三個“3”、第四個“4”。同樣,第二個孩子將創建 3 個孫執行緒并傳遞“5”、“6”、“7”數字。最后,第三個子執行緒將創建 4 個孫執行緒并傳遞“8”、“9”、“1”、“0”數字。

我想使用多執行緒并行傳遞所有這些值。我能夠在子執行緒之前讓一切正常作業,并且我能夠創建適量的孫執行緒,但是我無法將值傳遞給它們。非常感謝任何幫助和指導。

這是我的代碼:(請指導我修復它)

#include <iostream>
#include <pthread.h>
#include <math.h>
#include <fstream>
#include <sys/wait.h>
#include <cstdlib>
#include <unistd.h>
using namespace std;

struct info {
    int* digit = new int;
    int* totalDigits = new int;
};

struct grandchildThreadData {
    int GCTDdigit;
    int GCTDgrandchildIndex;
    int GCTDchildIndex;
    info* GCTDinfo = new info;
    info* GCTDparentInfo = new info;
};

struct childThreadData {
    long int CTDlineValue;
    int CTDchildIndex;
    info* CTDinfo = new info;
};

// thread declaration
void* childThread(void*);
void* grandchildThread(void*);

// function to convert and store line to digits
int* digitSeparator(long int);

// MAIN PROGRAM
int main() {
    // FILE OPENING
    int totalLines{0};
    ifstream file1("file.txt"), file2("file.txt");
    string temp;
    while (getline(file1, temp)) {
        totalLines  ;
    }
    file1.close();
    long int* valueOnLine = new long int[totalLines];
    int i =0;
    while (!file2.eof()) {
        file2 >> valueOnLine[i];
        i  ;
    }
    file2.close();
    // FILE CLOSING

    // THREAD START

    static struct info* mainInfo = new info[totalLines];
    pthread_t* child = new pthread_t[totalLines];
    // will be used to pass values to child
    static struct childThreadData* Carg = new childThreadData[totalLines];

    // Creating Childthreads
    for (int i = 0; i < totalLines; i  ) {
        Carg[i].CTDinfo[i] = mainInfo[i];
        Carg[i].CTDchildIndex = i;
        Carg[i].CTDlineValue = valueOnLine[i];

        if (pthread_create(&child[i], nullptr, childThread, &Carg[i])) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
    }

    // Joining Childthreads
    for (int i = 0; i < totalLines; i  ) {
        if (pthread_join(child[i], nullptr)) {
            fprintf(stderr, "Error joining thread\n");
            return 2;
        }
    }

    delete[] valueOnLine;
    delete[] child;
    delete[] Carg;

    return 0;
}

void* childThread(void* i) {
    struct childThreadData* CTptr = (struct childThreadData*)i;

    int totalDigits = log10((float)CTptr->CTDlineValue)   1;
    int* numberArray = digitSeparator(CTptr->CTDlineValue);
 
    // THIS LINE WILL PUT TOTAL DIGITS INTO mainInfo
    CTptr->CTDinfo[CTptr->CTDchildIndex].totalDigits[0] = totalDigits;

    static struct info* childInfo = new info[totalDigits];  // This can be used to print modified info in grandchild
    pthread_t* grandchild = new pthread_t[totalDigits];
    static struct grandchildThreadData* GCarg = new grandchildThreadData[totalDigits];

    // THIS LINE WILL PUT EACH DIGIT ON CORRECT LOCATION of mainInfo
    for (int i=0; i< totalDigits; i  ) {
        CTptr->CTDinfo[CTptr->CTDchildIndex].digit[i] = numberArray[i];
    }

    // GRANDCHILD THREAD
    for (int i = 0; i < totalDigits; i  ) {
        GCarg[i].GCTDinfo[i] = childInfo[i];    // grandchild to child communication but does not work
        // or
        GCarg[i].GCTDparentInfo[i] = CTptr->CTDinfo[i]; // grandchild to parent communication but does not work
        GCarg[i].GCTDgrandchildIndex = CTptr->CTDchildIndex;    // Here CTptr->CTDchildIndex should pass 0, 1, 2 to grandchild but I get different values
        GCarg[i].GCTDchildIndex = i; // This line works fine for some reason
        GCarg[i].GCTDdigit = CTptr->CTDinfo[CTptr->CTDchildIndex].digit[i]; // This line should pass the correct digit, but again, I am getting different results in grandchild
     
        if (pthread_create(&grandchild[i], nullptr, grandchildThread, &GCarg[i])) {
            fprintf(stderr, "Error creating thread\n");
        }
    }

    //Joining GrandChildthreads
    for (int i = 0; i < totalDigits; i  ) {
        if (pthread_join(grandchild[i], nullptr)) {
            fprintf(stderr, "Error joining thread\n");
        }
    }

    return nullptr;
}

void* grandchildThread(void* i) {
    struct grandchildThreadData* GCTptr = (struct grandchildThreadData*)i;

    // THIS LINE SHOULD PRINT THE DIGIT
    cout << GCTptr->GCTDdigit;

    return nullptr;
}

int* digitSeparator(long int number) {
    int totalDigits = log10((float)number)   1;
    int* separatorPtr = new int[totalDigits];
    int j = 0;

    for (int i = totalDigits - 1; i >= 0; i--) {
        long int divisor = pow((float)10, i);
        long int digit = number / divisor;
        number -= digit * divisor;
        separatorPtr[j] = digit;
        j  ;
    }

    return separatorPtr;
}

uj5u.com熱心網友回復:

該問題是由使用靜態結構引起的:

所以,如果我們替換:

static struct childThreadData* Carg = new childThreadData[totalLines];
static struct grandchildThreadData* GCarg = new grandchildThreadData[totalLines];

和:

childThreadData* Carg = new childThreadData[totalLines];
grandchildThreadData* GCarg = new grandchildThreadData[totalLines];

它會正常作業。

uj5u.com熱心網友回復:

這不是程式中問題的詳盡串列,但它涉及一些基本問題。

  • 您的程式不會檢查是否file.txt成功打開。如果不是,程式將繼續運行,直到出現有符號整數溢位——這意味著程式具有未定義的行為

  • 如果檔案成功打開,你會碰到堆的緩沖區溢位

    // Creating Childthreads
    for(int i = 0; i < totalLines; i  ) {
         Carg[i].CTDinfo[i] = mainInfo[i];        // <- here
    

    這是因為CTDinfo[i]是界限的時候了i > 0CTDinfo是指向一個單info-不totalLinesinfo

  • 下面一樣。CTDinfo不能被視為陣列,因為它是指向單個的指標info- 并且digit是指向單個的指標int- 而不是int.

    // THIS LINE WILL PUT EACH DIGIT ON CORRECT LOCATION of mainInfo
    for(int i = 0; i < totalDigits; i  ) {
         CTptr->CTDinfo[CTptr->CTDchildIndex].digit[i] = numberArray[i];
    }
    

建議:

  • 撰寫一個小得多的程式來掌握執行緒的竅門。
  • 撰寫一個小得多的程式來學習如何構建非常復雜的結構(如果你真的需要這樣做的話)。使用 C 類,例如std::vector. 如果您用標準 C 容器替換了所有手動記憶體管理,我懷疑該程式是否需要單個new/ new[]好像info發生了誤會之類的事情沒有理由在這里使用指標:
    struct info {
         int* digit = new int;
         int* totalDigits = new int;
    };
    
  • 使用std::thread其支持的函式和類,而不是在特定平臺的C API pthread

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/350163.html

標籤:C 多线程 孙子

上一篇:使用執行緒的并行TCP連接

下一篇:如何使用SpringBoot顯示從資料庫接收的blob影像

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more