您好,我正在编写一个代码,用于使用线程计算一个或多个文件中某个字母的出现次数。我必须为每个文件使用一个线程 e 使用互斥锁来修改全局总数。
这是我的代码:
typedef struct _CharFile{
char c;
char *fileName;
} CharFile;
pthread_mutex_t count = PTHREAD_MUTEX_INITIALIZER;
int sum = 0;
void *CountFile(void *threadarg);
int main(int argc, const char * argv[]) {
pthread_t threads[argc-2];
int chck, t;
CharFile cf;
if (argc <= 2){
perror("Wrong inputs: need to select a letter and one or more files\n");
exit(EXIT_FAILURE);
} else if (argc > 51) {
perror("Too many files\n");
exit(EXIT_FAILURE);
}
for ( t=0 ; t<argc-2 ; t++ ){
cf.c = argv[1][0];
cf.fileName = (char *)argv[t + 2];
chck = pthread_create(&threads[t], NULL, CountFile, (void *) &cf);
if (chck){
printf("ERROR; return code from pthread_create() is %d\n", chck);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < 2; i++)
pthread_join(threads[i], NULL);
printf("%lld occurrences of the letter %c in %lld threads\n", (long long)sum, argv[1][0], (long long)argc-2);
return 0;
}
void *CountFile(void *threadarg){
FILE *in;
CharFile *cf;
char c;
int counter = 0;
cf = (CharFile *) threadarg;
in = fopen(cf->fileName, "r");
if (in == NULL){
perror("Error opening the file!\n");
pthread_exit(NULL);
}
while (fscanf(in, "%c", &c) != EOF){
if(c == cf->c){
counter ++;
}
}
fclose(in);
pthread_mutex_lock(&count);
sum += counter;
printf("%d sum value, %d counter value \n", sum, counter);
pthread_mutex_unlock(&count);
pthread_exit(NULL);
}
我不知道哪里出了问题,但是使用我拥有的一些带有一堆字母的文件,结果很奇怪。
运行此行 ./a.out f file1.in lorem.txt notes.txt
两次我得到这些结果:
4 sum value, 4 counter value
9 sum value, 5 counter value
13 sum value, 4 counter value
13 occurrences of the letter f in 3 threads
4 sum value, 4 counter value
8 sum value, 4 counter value
12 sum value, 4 counter value
12 occurrences of the letter f in 3 threads
虽然如果我运行一个只有一个文件的更简单的命令行,计数是正确的,即 ./a.out f file1.in
5 sum value, 5 counter value
5 occurrences of the letter f in 1 threads
感谢您的帮助。
最佳答案
我想你的问题可能出在这里:
for ( t=0 ; t<argc-2 ; t++ ){
cf.c = argv[1][0];
cf.fileName = (char *)argv[t + 2];
chck = pthread_create(&threads[t], NULL, CountFile, (void *) &cf);
if (chck){
printf("ERROR; return code from pthread_create() is %d\n", chck);
exit(EXIT_FAILURE);
}
}
您向所有线程传递一个指向同一变量的指针(即 cf
)。将指针传递给第一个线程后,您更改 cf
的值并将指向它的指针传递给第二个线程,依此类推。
因此,在“刚刚启动”的线程读取其值之前,主循环可能会更改 cf
,即线程可能会打开另一个非预期的文件。
通过将 cf
更改为数组,确保每个线程都有自己的 cf
,即每个线程一个元素。
关于c - Mutex - 使用线程计算文件中 char 的出现次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46833529/