我正在解决这个问题:从命令行中取一个字母和相同文件的名称,计算每个文件中char的出现次数,每个文件使用一个线程,然后打印总出现次数。
这是我的代码:
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;
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(-1);
}
}
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 += 1;
}
}
fclose(in);
pthread_mutex_lock(&count);
sum += counter;
pthread_mutex_unlock(&count);
pthread_exit(NULL);
}
我没有在文件打开或线程创建中出现任何错误,但我的输出始终为0,因为总出现次数。我还尝试在线程中打印counter
,并且每次在所有线程中都得到相同的数字,即使我的输入文件不同。我错误地使用互斥锁还是有其他错误?
这是我的输出之一:
61 occurrences of e in this thread
0 occurrences of the letter e in 3 threads
61 occurrences of e in this thread
61 occurrences of e in this thread
Program ended with exit code: 9
答案 0 :(得分:0)
这里有几个线程问题。
1)主线程将与新生成的线程异步地继续。给定代码,主线程很可能在CountFile线程完成之前完成并退出。在Linux上,当主线程返回时,C运行时将执行exit_group系统调用,该调用将终止所有线程。
您需要添加一些检查以确保CountFile线程已完成相关的工作部分。在此示例中,请查看在主线程中使用pthread_join()。
2)&#39; cf&#39;主线程中的存储是一个堆栈局部变量,它由指针传递给每个线程。但是,由于它是相同的存储,可能会发生几种类型的故障。 a)工作单元可以在工作线程访问它时由主线程更新。 b)将相同的工作单元发送到多个/所有线程。
您可以通过以下几种方式解决这个问题:&#39; cf&#39;可以是每个线程的CharFile数组。或者&#39; cf&#39;可以为每个线程动态分配。前者的性能和内存效率要高一些,但后者可能在结构上更好。特别是主线程在其本地堆栈空间中将地址提供给另一个线程。
3)一旦#1项被寻址并且线程在主线程printf之前退出,则互斥量使用就可以了。但是将pthread_mutex_locks放在&#39; sum&#39;的主线程访问周围可能会更好。无论如何。给定此代码可能没有必要,但未来的代码重构可能会改变它。