c - 使用没有互斥锁的线程增加全局变量会奇怪地返回正确的值

标签 c multithreading pthreads global mutex

我们被要求创建 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/

上一篇:c - 使用od命令

下一篇:c - 空指针问题

相关文章:

c - 为什么 strlen 函数在没有 #include<string.h> 的情况下也能工作?

c - 如何克隆 GtkWindow 及其内容?

c - c 中的全局计数器未按预期工作

linux - 为什么在 gcc 中覆盖 union 成员没有警告?

C++ 如果一个线程写入后切换一个 bool 值,那么在另一个线程的循环中读取该 bool 值是否安全?

C pthreads send()ing 和 recv()ing 在套接字上。分开工作但没有一起工作。不会退出

linux - 等待线程如何知道共享资源已被另一个线程解锁?

java - 如何使用多个CommandLineRunner运行Spring Boot App

c - 在线程不安全函数上使用锁定和复制

c - 时间片的问题