使用 Win32 的多线程
Multiple Threads using Win32
我正在用 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] = '[=10=]';
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;
}
正如Jonathan Potter指出的那样
"Every thread will need its own ThreadInfo"
我正在用 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] = '[=10=]';
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;
}
正如Jonathan Potter指出的那样
"Every thread will need its own ThreadInfo"