我有一個具有以下值的 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 > 0。CTDinfo是指向一個單info-不totalLines的info第下面一樣。
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 APIpthread。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/350163.html
上一篇:使用執行緒的并行TCP連接
