C多线程程序行为解释

时间:2015-02-08 21:10:43

标签: c multithreading race-condition

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在print1到达printf之前增加和printf。
  2. 这不会弄乱2&gt; 10?
  3. 中的数字
  4. 我也很想了解pthread_join在这个程序中的功能。我的理解是它用于等待线程完成。是否在等待pthread_create启动的writeloop函数?
  5. writeloop(null)是否被视为第二个帖子?

2 个答案:

答案 0 :(得分:2)

  1. g_ant++; 不是原子操作,可能导致未定义的行为。你应该使用
    pthread_mutex_lock(&mutex);pthread_mutex_unlock(&mutex); 90%次从2开始的原因是因为线程time进入函数,增加g_ant并自行休眠。操作系统倾向于将它从CPU中取出并放在另一个没有睡眠的线程中,在你的情况下,这是你的主线程,再次将它增加1次运行睡眠。现在g_ant的值为2,线程time恢复并打印2并将其递增为3.主线程恢复并打印3并再次递增它,这样就可以切换为什么你看到2中的数字 - &GT;大部分时间都是10个。
  2. 希望它足够清楚并且应该回答2.问题。

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

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

      希望它有所帮助。

答案 1 :(得分:2)

  
      
  1. 主线程被认为是另一个线程。以下内容可能有助于您了解在添加互斥锁之前发生了什么(假设   你必须这样做下一步)。通常,您不会退出()整个过程   从一个线程 - 它永远不会在主线程中加入。
  2.   
#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;
 }