以下是我的线程学习测试代码:

int mylock = 0;

void *r1(void *x)
{
  puts("entered r1");
  int *p;
  p = (int *)x;
  int i = *p;
  sleep(1);
  *p = --i;
  printf("r1: %d\n",*p);
  mylock = 1;
  printf("r1: done\n");
#ifdef USETHREADS
  pthread_exit(0);
#endif
}

void *r2(void *x)
{
  puts("entered r2");
  if (!mylock) {
          puts("r2 is waiting...");
          while (!mylock)
                printf("");
  }
  int *p;
  p = (int *)x;
  int i = *p;
  *p = ++i;
  sleep(1);
  printf("r2: %d\n",*p);
  printf("r2: done\n");
#ifdef USETHREADS
  pthread_exit(0);
#endif
}

main()
{
  int i1,i2;
  i1 = 1;
  i2 = 2;
  printf("i1: %d\n", i1);
#ifdef USETHREADS
  pthread_t r1_thread, r2_thread;
  pthread_create(&r1_thread, NULL, r1, &i1);
  pthread_create(&r2_thread, NULL, r2, &i1);
  pthread_join(r1_thread, NULL);
  pthread_join(r2_thread, NULL);
#else
  r1(&i1);
  r2(&i1);
#endif
  printf("i1: %d\n", i1);
  return 0;
}

所以有两个线程,一个在增加i1,一个在减少(我知道pthreads中有“mutex”,但目前还没有使用),所以为了避免竞争条件,我创建了mylock(我猜它伪造了mutex),让我吃惊的是,进程在等待mylock更改值时被困在一个未定义的循环中,除非我在等待循环中调用printfPrimtf调用它的出口正如预期2秒,这是Linux的神秘?

最佳答案

您的程序通过访问mylock而不进行同步来调用未定义的行为。在访问之前,您需要调用pthread_mutex_lock(在您选择保护mylock状态的互斥体上),完成后调用pthread_mutex_unlock。当然,那么mylock可能是无用的;您可以直接使用pthread_mutex_lock进行锁定。
也就是说,如果你想学习线程,你的方法是完全错误的。一开始你不会试图滚动你自己的同步原语。在很大程度上,你不应该这样做,即使你是一个专家,除非你有非常不寻常的需要,即使这样,这可能是一个坏主意。给自己一个好的线程教程,教你如何正确使用同步原语,然后使用它们。

10-04 12:52