Проблема в том, что вы не можете использовать этот макрос для назначения (в теле функции).Вместо этого вы должны использовать:
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;
}