использовать массив условной переменной pthread внутри структуры - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь создать пример 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 } }

Каков наилучший подход для создания массива объектов синхронизации pthead внутри struct и последующего использования его в функциях.

Заранее спасибо.

1 Ответ

0 голосов
/ 14 декабря 2018

Проблема в том, что вы не можете использовать этот макрос для назначения (в теле функции).Вместо этого вы должны использовать:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...