2015-10-20 5 views
1

Я пишу многопоточный счетчик символов ASCII в C. Программа работает по желанию, когда я устанавливаю NUM_THREADS в 1, но он сбой с любым другим числом. Это мое первое многопоточное задание с переменным многообразием, и я думал, что все понимаю, но, полагаю, я что-то упускаю.Несколько потоков с использованием Win32

Вот что у меня есть:

#include <stdio.h> 
#include <windows.h> 

#define BUF_SIZE 65536 
#define NUM_THREADS 2 

struct ThreadInfo { 
    char buffer[BUF_SIZE]; 
    int threadNum; 
    int firstIndex; 
    int lastIndex; 
}; 


int char_count[NUM_THREADS][128]; 
int bytesRead = 0; 

DWORD WINAPI countChars(struct ThreadInfo *threadInfo); 

int main(int argc, char* argv[]){ 
    DWORD ThreadId[NUM_THREADS]; 
    HANDLE ThreadHandles[NUM_THREADS]; 
    struct ThreadInfo threadInfo; 
    char buffer[BUF_SIZE]; 

    buffer[BUF_SIZE - 1] = '\0'; 

    if(argc < 2){ 
     printf("Usage Error: Incorrect number of arguments.\n"); 
     printf("Usage: ASCIICount <file1>\n"); 
     return 1; 
    } 

    for(int i = 0; i < NUM_THREADS; i++){ 
     for (int j = 0; j < sizeof(char_count); j++) { 
      char_count[i][j] = 0; 
     } 
    } 

    HFILE file1 = CreateFile(argv[1], 
     GENERIC_READ, 
     0, 
     NULL, 
     OPEN_EXISTING, 
     FILE_ATTRIBUTE_NORMAL, 
     NULL); 

    if(file1 == INVALID_HANDLE_VALUE){ 
     printf("Error opening %s.\n", argv[1]); 
     return 1; 
    } 

    ReadFile(file1, buffer, sizeof(buffer)-1, &bytesRead, NULL); 

    strcpy(threadInfo.buffer, buffer); 

    for (int i = 0; i < NUM_THREADS; i++) { 
     threadInfo.threadNum = i; 
     threadInfo.firstIndex = (i)*((bytesRead/NUM_THREADS)); 
     threadInfo.lastIndex = (i+1)*(bytesRead/NUM_THREADS) - 1; 

     ThreadHandles[i] = CreateThread(
      NULL, //default security attributes 
      0, // default stack size 
      countChars, // thread function 
      &threadInfo, // parameter to thread function 
      0, // default creation flags 
      &ThreadId[i]); 
    } 

    for (int i = 0; i < NUM_THREADS; i++) { 
     if (ThreadHandles[i] != NULL) { 
      // now wait for the thread to finish 
      WaitForSingleObject(ThreadHandles[i], INFINITE); 

      //close the thread handle 
      CloseHandle(ThreadHandles[i]); 
     } 
    } 

    printf("Buffer size: %d\n", sizeof(buffer)); 
    printf("Bytes read: %d\n", bytesRead); 
    for (int i = 0; i < NUM_THREADS; i++) { 
     for (int j = 0; j < 128; j++) { 
      if (j < 33 || j == 127) { 
       printf("%d, %#x, %d\n", j, j, char_count[i][j]); 
      } 
      else { 
       printf("%d, %c: %d\n", j, j, char_count[i][j]); 
      } 
     } 
    } 
    return 0; 
} 

DWORD WINAPI countChars(struct ThreadInfo *threadInfo){ 
    char cur_char; 
    for(int i = threadInfo->firstIndex; i < threadInfo->lastIndex; i++){ 
     cur_char = threadInfo->buffer[i]; 
     char_count[threadInfo->threadNum][cur_char]++; 
    } 
    return 0; 
} 
+0

Я думаю, я просто понял, что это. Я изменяю значение threadInfo после создания потока, который использует этот threadInfo. Таким образом, решение будет состоять из массива из NUM_THREADS threadInfos –

+0

Каждому потоку будет нужна его собственная «ThreadInfo», в настоящий момент они все используют один и тот же. –

+0

Дин динг динг. Спасибо! –

ответ

1

Как Jonathan Potter отметил

"Каждый поток будет нуждаться в собственной ThreadInfo"

 Смежные вопросы

  • Нет связанных вопросов^_^