【问题标题】:Using mutex for pthread results in random answer对 pthread 使用 mutex 会导致随机答案
【发布时间】:2013-04-04 12:46:03
【问题描述】:

我写了一个简单的pthread代码

#include <pthread.h>
#include <stdio.h>
#include <math.h>

#define ITERATIONS 500

// A shared mutex
pthread_mutex_t mutex;
int target;

void* opponent(void *arg)
{
  int i;
  printf("opp, before for target=%d\n", target);
  pthread_mutex_lock(&mutex);
  for(i = 0; i < ITERATIONS; ++i)
  {
    target++;
  }
  pthread_mutex_unlock(&mutex);
  printf("opp, after for target=%d\n", target);

  return NULL;
}

int main(int argc, char **argv)
{
  pthread_t other;

  target = 5;

  // Initialize the mutex
  if(pthread_mutex_init(&mutex, NULL))
  {
    printf("Unable to initialize a mutex\n");
    return -1;
  }

  if(pthread_create(&other, NULL, &opponent, NULL))
  {
    printf("Unable to spawn thread\n");
    return -1;
  }

  int i;
  printf("main, before for target=%d\n", target);
  pthread_mutex_lock(&mutex);
  for(i = 0; i < ITERATIONS; ++i)
  {
    target--;
  }
  pthread_mutex_unlock(&mutex);
  printf("main, after for target=%d\n", target);

  if(pthread_join(other, NULL))
  {
    printf("Could not join thread\n");
    return -1;
  }

  // Clean up the mutex
  pthread_mutex_destroy(&mutex);

  printf("Result: %d\n", target);

  return 0;
}

然后我用这个命令编译

gcc -pedantic -Wall -o theaded_program pth.c -lpthread

但是,每次运行程序,我都会得到不同的结果!!

 $ ./theaded_program
 main, before for target=5
 main, after for target=-495
 opp, before for target=5
 opp, after for target=5
 Result: 5

 $ ./theaded_program
 main, before for target=5
 opp, before for target=5
 opp, after for target=5
 main, after for target=-495
 Result: 5

【问题讨论】:

    标签: c pthreads mutex


    【解决方案1】:

    当互斥锁被锁定并且它们正在访问target时,printf()语句不会被执行:

    printf("opp, before for target=%d\n", target);
    pthread_mutex_lock(&mutex);
    

    这意味着一个线程可能会更改target 的值,而另一个线程正在尝试读取它(在printf() 中)。移动要在互斥锁锁定时执行的printf() 语句:

    pthread_mutex_lock(&mutex);
    printf("opp, before for target=%d\n", target);
    /* snip */
    printf("opp, after for target=%d\n", target);
    pthread_mutex_unlock(&mutex);
    

    这将防止target 被一个线程读取并同时被另一个线程修改。但是,不能保证哪个线程将首先获取互斥锁。

    【讨论】:

    • 那有什么解决办法?
    【解决方案2】:

    这个结果符合预期,你的代码保证main和对手没有做

    for(i = 0; i < ITERATIONS; ++i)
    {
      target--; //or ++ for the opponent
    }
    

    同时。

    printfs 不受互斥体的任何保护。为了避免这种情况在互斥锁/解锁中插入printfs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多