在结构内使用pthread条件变量数组

时间:2018-12-14 10:50:33

标签: c pthreads

我正在尝试创建pthread示例,该示例将在结构中创建pthread条件和pthread互斥量,然后在功能中使用该条件和互斥变量。

我的来源是:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>

struct SubObj {
  //pthread_mutex_t *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
  //pthread_cond_t *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
  pthread_cond_t *cond;
  pthread_mutex_t *mutex;
} subobj;

const size_t NUMTHREADS = 4;

int done = 0;

void* ThreadEntry(void* id) 
{
  const int myid = (long) id;
  const int workloops = 200;

  printf("[thread %d] done is now %d. Signalling cond.\n", myid, done);

  for (int i = 0; i < workloops; i++) 
  {
      printf("[thread %d] working (%d/%d)\n", myid, i, workloops);
  }

  pthread_mutex_lock(&subobj.mutex);
  done++;
  pthread_mutex_unlock(&subobj.mutex);
  pthread_cond_signal(&subobj.cond);

  return NULL;
}

int main(int argc, char** argv) 
{
  subobj.mutex = PTHREAD_MUTEX_INITIALIZER;
  subobj.cond = PTHREAD_COND_INITIALIZER;

  pthread_t threads[NUMTHREADS];

  for (int t = 0; t < NUMTHREADS; t++)
      pthread_create(&threads[t], NULL, ThreadEntry, (void*) (long) t);

  pthread_mutex_lock(&subobj.mutex);

  while (done < NUMTHREADS) 
  {
      printf("[thread main] done is %d which is < %d so waiting on cond\n",
            done, (int) NUMTHREADS);

      pthread_cond_wait(&subobj.cond, &subobj.mutex);
  }

  printf("[thread main] done == %d so everyone is done\n", (int) NUMTHREADS);

  pthread_mutex_unlock(&subobj.mutex);

  return 0;
}

但是在编译此源代码后,它给了我错误。真的为此度过了一段糟糕的时光。

[ Compiling source file (condInStruct.c) to bitcode 
(../obj/condInStruct.c.prof.bc) ]
condInStruct.c:49:17: error: expected expression
    subobj.mutex = PTHREAD_MUTEX_INITIALIZER;
                   ^
/usr/include/pthread.h:87:3: note: expanded from macro ' 

 PTHREAD_MUTEX_INITIALIZER'
  { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
  ^
 condInStruct.c:50:16: error: expected expression
    subobj.cond = PTHREAD_COND_INITIALIZER;
                  ^
/usr/include/pthread.h:186:34: note: expanded from macro 
'PTHREAD_COND_INITIALIZER'
#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }

在struct中创建pthead同步对象数组,然后在功能中使用它的最佳方法是什么。

谢谢。

1 个答案:

答案 0 :(得分:2)

问题是您不能使用此宏进行分配(在函数体内)。您应该使用:

pthread_mutex_init(&subobj.mutex, NULL);
pthread_cond_init(&subobj.cond, NULL);

相反。让我们通过查看预处理器输出来调查原因:

subobj.mutex = 
# 39 "main.c" 3 4
            { { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } }

这是行的预处理输出:

 subobj.mutex = PTHREAD_MUTEX_INITIALIZER;

仅在声明期间才允许这种分配。

完整代码:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>

struct SubObj {
  //pthread_mutex_t *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
  //pthread_cond_t *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
  pthread_cond_t cond;
  pthread_mutex_t mutex;
} subobj;

const size_t NUMTHREADS = 4;

int done = 0;

void* ThreadEntry(void* id) 
{
  const int myid = (long) id;
  const int workloops = 200;

  printf("[thread %d] done is now %d. Signalling cond.\n", myid, done);

  for (int i = 0; i < workloops; i++) 
  {
      printf("[thread %d] working (%d/%d)\n", myid, i, workloops);
  }

  pthread_mutex_lock(&subobj.mutex);
  done++;
  pthread_mutex_unlock(&subobj.mutex);
  pthread_cond_signal(&subobj.cond);

  return NULL;
}

int main(int argc, char** argv) 
{
  pthread_mutex_init(&subobj.mutex, NULL);
  pthread_cond_init(&subobj.cond, NULL);
  pthread_t threads[NUMTHREADS];

  for (int t = 0; t < NUMTHREADS; t++)
      pthread_create(&threads[t], NULL, ThreadEntry, (void*) (long) t);

  pthread_mutex_lock(&subobj.mutex);

  while (done < NUMTHREADS) 
  {
      printf("[thread main] done is %d which is < %d so waiting on cond\n",
            done, (int) NUMTHREADS);

      pthread_cond_wait(&subobj.cond, &subobj.mutex);
  }

  printf("[thread main] done == %d so everyone is done\n", (int) NUMTHREADS);

  pthread_mutex_unlock(&subobj.mutex);

  return 0;
}