我在C中编写一个多线程ASCII字符计数器。当我将NUM_THREADS设置为1时,程序可以正常工作,但它会与任何其他数字崩溃。这是我的第一个可变的多线程任务,我认为我理解了一切,但我想我错过了一些东西。
这就是我所拥有的:
#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;
}