3

我写了一个简单的 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
4

2 回答 2

2

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

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被一个线程读取并同时被另一个线程修改。但是,不能保证哪个线程将首先获取互斥锁。

于 2013-04-04T12:49:56.573 回答
1

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

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

同时。

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

于 2013-04-04T12:50:18.820 回答