我们被要求创建 4 个线程,每个线程递增( SPIN
/4 倍)全局变量 compteur
的值。据说每个线程都在另一个线程完成迭代之前访问/更改全局变量(这就是为什么 SPIN
被赋予一个非常大的数字),例如线程号 1 访问 compteur
首先,当它增加另一个线程访问 Compteur 时,会看到 compteur = 0
尽管如此,最终的结论是我们必须使用 MUTEX。
问题是程序总是给我与 SPIN 相同的值,而它不应该这样做。
你能解释一下为什么吗?
#define SPIN 40000000
int compteur = 0;
void *routine_thread(void *arg) {
int i;
printf("accessing thread ... \n");
for (i = 0; i < SPIN / 4; ++i) {
compteur++;
}
printf("quitting thread ... \n");
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_t thread_id[4];
void *resultat_thread;
int statut;
int i;
for (i = 0; i < 4; i++) {
statut = pthread_create(&thread_id[i], NULL, routine_thread, NULL);
if (statut != 0) {
fprintf(stderr, "error creating thread\n");
exit(EXIT_FAILURE);
}
statut = pthread_join(thread_id[i], &resultat_thread);
if (statut != 0) {
fprintf(stderr, "error joining the thread\n");
exit(EXIT_FAILURE);
}
}
printf("compteur value is : %d\n", compteur);
if (resultat_thread == NULL)
return EXIT_FAILURE;
else
return EXIT_SUCCESS;
}
最佳答案
您已经序列化了正在创建的线程。循环内的 pthread_join()
调用会等待线程完成,然后再创建下一个线程。
因此,在任何时候,您都只有一个事件线程(主线程除外)来修改 compteur
。所以没有data race您期望观察到的。
从循环中删除 pthread_join
调用。并进行另一个循环来等待线程:
for(i= 0; i< 4; i++) {
statut = pthread_join(thread_id[i], NULL);
if(statut != 0) {
fprintf(stderr, "error joining the thread\n");
exit(EXIT_FAILURE);
}
}
您的线程函数不返回任何值。因此,您可以在 pthread_join
调用中使用 NULL
而不是 &resultat_thread
。
关于c - 使用没有互斥锁的线程增加全局变量会奇怪地返回正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49278946/