2015-12-09 63 views
-3

我正在爲這個代碼苦苦掙扎。這是關於從文本文件中計算一些模式。我試圖使用線程(除法和征服)處理,但它返回了一個錯誤的值。我使用互斥量值來同步臨界區。代碼如下。第一個主要參數是線程數,第二個是我希望從中計數模式的文本文件的名稱,以及我希望查看文本的以下模式。 請救救我吧..我在多線程中遇到了一些問題

代碼如下


char *buffer; 
int fsize, count; 
char **searchword; 
int *wordcount; 
int *strlength; 

typedef struct _params{ 
int num1; 
int num2; 
}params; 

pthread_mutex_t mutex; 

void *childfunc(void *arg) 
{ 

int size, i, j, k, t, start, end, len, flag = -1; 

int result; 

params *a = (params *)arg; 
start = a->num1; 
end = a->num2; 


while(1){ 

if(start == 0 || start == fsize) 
break; 
if(buffer[start]!= ' ' && buffer[start] != '\n' && buffer[start] != '\t') 
start++; 
else 
break; 
} 

while(1){ 

if(end == fsize) 
break; 
if(buffer[end] != ' ' && buffer[end] != '\n' && buffer[end] != '\t') 
end++; 
else 
break; 
} 

for(i = 0; i < count; i++){ 

len = strlength[i]; 
for(j = start; j<(end - len + 1); j++){ 

if(buffer[j] == searchword[i][0]){ 

flag = 0; 
for(k = j +1; k<j + len; k++){ 
if(buffer[k] != searchword[i][k-j]) 
{ 
flag = 1; 
break; 

} 

} 
if(flag == 0){ 

pthread_mutex_lock(&mutex); 
wordcount[i]++; 
pthread_mutex_unlock(&mutex);// mutex unlocking 
sleep(1); 
flag = -1; 

} 
} 

} 

} 

} 

int main(int argc, char **argv){ 

FILE *fp; 
char *inputFile; 
pthread_t *tid; 
int *status; 
int inputNumber, i, j, diff, searchstart, searchend; 
int result = 0; 

count = argc -3; 
inputNumber = atoi(argv[1]); 
inputFile = argv[2]; 

searchword = (char **)malloc(sizeof(char *)*count); 
tid = malloc(sizeof(pthread_t)*inputNumber); 
strlength = (int *)malloc(4*count); 
status = (int *)malloc(4*inputNumber); 
wordcount = (int *)malloc(4*count); 

for(i = 0; i < count; i++) 
searchword[i] = (char*)malloc(sizeof(char)*(strlen(argv[i+3]) + 1)); 
for(i = 3; i < argc; i++) 
strcpy(searchword[i-3], argv[i]); 
fp = fopen(inputFile, "r"); 
fseek(fp, 0, SEEK_END); 
fsize = ftell(fp); 
rewind(fp); 
buffer = (char *)malloc(1*fsize); 

fread(buffer, fsize, 1, fp); 

diff = fsize/inputNumber; 
if(diff == 0) 
diff = 1; 

for(i = 0; i < count ; i++){ 
strlength[i] = strlen(searchword[i]);  
wordcount[i] = 0; 
} 


for(i = 0; i < inputNumber; i++){ 

searchstart = 0 + i*diff; 
searchend = searchstart + diff; 

if(searchstart > fsize) 
searchstart = fsize; 

if(searchend > fsize) 
searchend = fsize; 

if(i == inputNumber -1) 
searchend = fsize; 
params a; 
a.num1 = searchstart; 
a.num2 = searchend; 

pthread_mutex_init(&mutex, NULL); 

result = pthread_create(&tid[i], NULL, childfunc, (void *)&a); 

if(result < 0){ 
perror("pthread_create()"); 
} 

} 

//스레드 받는 부분 

for(i = 0; i < inputNumber; i++){ 
result = pthread_join(tid[i], (void **)status); 

if(result < 0) 
perror("pthread_join()"); 
} 
pthread_mutex_destroy(&mutex); // mutex 해제 
for(i = 0; i < count; i++) 
printf("%s : %d \n", searchword[i], wordcount[i]); 

for(i = 0; i < count; i++) //동적메모리해제 
free(searchword[i]); 
free(searchword); 

free(buffer); 
free(tid); 
free(strlength); 
free(wordcount); 
free(status); 

fclose(fp); 


return 0; 
} 

回答

0
params a; // new a for each loop, previous a no longer exists 
a.num1 = searchstart; 
a.num2 = searchend; 

pthread_mutex_init(&mutex, NULL); 

result = pthread_create(&tid[i], NULL, childfunc, (void *)&a); 

if(result < 0){ 
perror("pthread_create()"); 
} 

} // a goes out of scope here 

您通過每個線程的a地址,但隨後a超出範圍在創建線程之後。所以線程現在有堆棧上隨機剩餘垃圾的地址。

您需要對多個線程訪問的任何對象擁有一些所有權的概念,例如a就在這裏。它可以由稱爲pthread_create的線程擁有,由新創建的線程擁有,或共同擁有。但你必須保持一致。你沒有這些,爲什麼?

a擁有唯一的線程,調用pthread_create?不,因爲新創建的線程有一個指向它的指針並通過該指針訪問它。所以調用pthread_create的線程不能銷燬它。

a只擁有由pthread_create創建的線程嗎?不,因爲它位於調用pthread_create的線程棧中,並且在下一個循環出現時將不再存在。

a共同所有?嗯,不,因爲調用pthread_create的線程可以在之前破壞對象,新創建的線程可以訪問它。

因此沒有多線程使用的理智模型後跟a。它壞了。

這個問題的一個常見解決方案是爲每個線程分配一個新結構(使用mallocnew),填充它並將結構的地址傳遞給線程。線程free(或delete)在完成它的結構。

+0

謝謝。你給了我一個見解。現在我要試試它! –

相關問題