如何在最后一次线程调用后重置变量?

时间:2016-12-10 22:51:55

标签: c pthreads mutex

我一直在尝试学习pthreads,使用互斥锁和cond,但是我不知道如何在使用它的最后一个线程不再需要它之后重置变量。

我有以下代码:

int i = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;

int test() {
  if (i == 0) {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
  }
  pthread_mutex_lock(&mutex);
  ++i;

  if (i % 5 != 0) {
    pthread_cond_wait(&cond, &mutex);
  }

  else {
    pthread_cond_broadcast(&cond);
  }

  int j = i;

  i = 0; /* problem line */
  pthread_mutex_unlock(&mutex);
  //i = 0; /* tried here too */

  return j;
}

我有多个线程调用此test()方法。

前4个线程将一直等到第5个线程被调用,然后所有5个线程将​​返回5。但是第6 +将返回' 6' 7',等等,我想重置i变量i = 0,因此计数将重新启动。

我想做另一个thread_cond_t让线程等到所有j = i完成。但我认为这是对的(或者至少是不必要的)。

实际输出是(因线程而未确定的顺序):

0
0
0
0
5
0
0
0
5

我希望他们都是5 s。

编辑:我将j设为全局,i在广播后进行了修改,目前已有效:

int i = 0, j;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int test() {
  pthread_mutex_lock(&mutex);
  ++i;

  if (i % 5 != 0) {
    pthread_cond_wait(&cond, &mutex);
  } else {
    pthread_cond_broadcast(&cond);
    j = i;
  }
  i = 0;
  pthread_mutex_unlock(&mutex);

  return j;
}

此代码在达到5后成功重置变量,并在所有线程上打印该值,但是当我尝试多个线程时,我似乎遇到了数据集。

1 个答案:

答案 0 :(得分:0)

  

此代码在达到5后成功重置变量,并在所有线程上打印该值,但是当我尝试多个线程时,似乎出现了数据争用的情况。

在编辑后的代码中,请考虑以下过程:pthread_cond_wait中有四个线程正在等待,第五个线程刚刚通过了pthread_cond_broadcast(导致前四个线程在返回之前挂在{{​​1}}上)来自mutex),并且第六个线程已经在pthread_cond_wait中等待。现在,在设置pthread_mutex_lock之后,第五个通过i = 0,并说第六个以pthread_mutex_unlock继续,将++i设置为 1 ,然后等待i(导致pthread_cond_wait解锁)。然后,前四个线程之一将继续并通过mutex,因此计数器i = 0会被重置。
要解决此问题,请仅在执行i的线程中重置i,即。 e。改变

pthread_cond_broadcast

  }
  i = 0;

(将 i = 0; } 移到i = 0块中)。