【问题标题】:C multithread program behaviour explanationC多线程程序行为解释
【发布时间】:2015-04-08 13:55:58
【问题描述】:
int g_ant = 0;
void *writeloop(void *arg)
 {
 while(g_ant < 10)
  {
  g_ant++;
  usleep(rand()%10);
  printf("%d\n", g_ant);
  }
 exit(0);
 }

int main(void)
 {
 pthread_t time;
 pthread_create(&time, NULL, writeloop, NULL);
 writeloop(NULL);
 pthread_join(time, NUL);
 return 0;
 }

嗨!我有四个我认为属于竞赛条件的问题......? :-)

  1. 我试图弄清楚为什么 g_ant 的 printf 在我的计算机上从 2 开始并在 90% 的情况下持续到 10,偶尔会输出 1、3->10。我的猜测是因为 usleep 可能会阻碍 thread1 足够长的时间以让 thread2 在 thread1 到达 printf 之前递增和 printf。
  2. 这不是也会把 2->10 的数字弄乱吗?
  3. 我也在努力理解 pthread_join 在这个程序中的功能。我的理解是它用于等待线程完成。是在等待 pthread_create 启动的 writeloop 函数吗?
  4. 是否将 writeloop(null) 视为第二个线程?

【问题讨论】:

    标签: c multithreading race-condition


    【解决方案1】:
    1. g_ant++; 不是原子操作,这可能会导致未定义的行为。你应该使用
      pthread_mutex_lock(&amp;mutex);pthread_mutex_unlock(&amp;mutex); 它 90% 次从 2 开始的原因是因为线程 time 进入函数,递增 g_ant 并自行休眠。操作系统倾向于将其从 CPU 中取出并放在那里另一个没有睡着的线程,在你的情况下,这是你的主线程,它再次将它增加 1 运行睡眠。现在 g_ant 的值为 2,线程 time 恢复并打印 2 并将其递增到 3。主线程被恢复并打印 3 并再次递增它,这会不断切换,这就是为什么您大部分时间会看到 2 -> 10 的数字.

    希望它足够清楚,也应该回答 2. 问题。

    1. pthread_join 确保其他线程在您的主线程退出程序之前完成它们的工作。

    2. 不,它不被视为第二个线程,它在主线程上运行函数。

      希望对你有帮助。

    【讨论】:

      【解决方案2】:
      1. 主线程被认为是另一个线程。以下内容可能会帮助您了解在添加互斥锁之前发生了什么(假设 接下来你必须这样做)。通常,您不会 exit() 整个过程 从一个线程 - 它永远不会加入到主线程中。
      #include <pthread.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
      
      int g_ant = 0;
      
      void *writeloop(void *arg)
      {
          while(g_ant < 10)
          {
              g_ant++;
              usleep( rand() % 10 );
              printf("thread: %u global: %d\n", (unsigned int)pthread_self(), g_ant);
          }
          return NULL;
      }
      
      int main(void)
       {
          pthread_t t;
          pthread_create(&t, NULL, writeloop, NULL);
          writeloop(NULL);
          pthread_join(t, NULL);
          printf("Joined\n");
          return 0;
       }
      

      【讨论】:

      • 您对互斥锁部分是正确的。感谢您的示例:)
      猜你喜欢
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 2021-03-28
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      相关资源
      最近更新 更多