我有以下程序(缩写)来使用线程计算每个字母在文件中出现的次数:
#define N_LETTERS 26U
#define IS_LETTER(x) (x >= 'A' && x <= 'Z')
#define HASH(x) toupper(x) - 'A'
typedef unsigned int uint;
typedef struct {
uint nt;
uint nc;
char filename[128];
} Args;
Args args = {0};
char *file_contents = NULL;
uint file_size;
uint chars_per_thread;
pthread_mutex_t mutex;
uint letter_count[N_LETTERS] = {0};
void get_program_args(int argc, char **argv) {
...
}
uint read_file(char *filename, char **buffer) {
....
return file_size;
}
void *count_letters(void *arg) {
uint start = *((int *)arg);
uint end = (start + chars_per_thread) >= file_size ? file_size : (start + chars_per_thread);
uint count[N_LETTERS] = {0};
for (uint i = start; i < end; i++) {
char c = toupper(file_contents[i]);
if (IS_LETTER(c)) {
count[HASH(c)]++;
}
}
pthread_mutex_lock(&mutex);
for (int i = 0; i < N_LETTERS; i++) {
letter_count[i] += count[i];
}
pthread_mutex_unlock(&mutex);
return NULL;
}
float letter_sum() {
...
return sum;
}
void print_letter_count() {
...
}
int main(int argc, char **argv) {
uint chars_counted = 0;
get_program_args(argc, argv);
file_size = read_file(args.filename, &file_contents);
pthread_mutex_init(&mutex, NULL);
pthread_t *threads = malloc(args.nt * sizeof(pthread_t));
if (threads == NULL) {
printf("Error allocating memory. \n");
exit(EXIT_FAILURE);
}
chars_per_thread = (file_size / args.nt) > args.nc ? args.nc : (file_size / args.nt);
while (chars_counted < file_size) {
for (int i = 0; i < args.nt; i++) {
uint start = chars_counted;
if (start >= file_size)
break;
pthread_create(&threads[i], NULL, count_letters, &start);
chars_counted += chars_per_thread;
}
for (int i = 0; i < args.nt; i++) {
pthread_join(threads[i], NULL);
}
}
print_letter_count();
pthread_mutex_destroy(&mutex);
free(threads);
free(file_contents); // free allocated memory
return 0;
}
每次我使用超过 1 个线程运行程序时,我都会得到不同的答案,看起来好像我有竞争条件,但我找不到它。有人能帮我吗?
我尝试使用互斥锁来修复它,但仍然存在相同的问题。
不知道为什么@yano 没有将他们的评论作为答案,但这就是问题所在。你传递一个指针到start
当你启动每个线程时,然后你去改变它的值start
当该线程正在尝试读取它时!您需要一个起始值数组,并将一个指针传递给该线程自己的起始值的个人副本(该副本不会更改)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)