Статическая инициализация мьютекса pthreads

Как, используя pthreads, в C инициализировать статический массив мьютексов?

Кажется, для одного статического мьютекса я могу использовать PTHREAD_MUTEX_INITIALIZER. Но как насчет их статического массива? Как, например,

#include <pthread.h>
#define NUM_THREADS 5

/*initialize static mutex array*/
static pthread_mutex_t mutexes[NUM_THREADS] = ...?

Или они должны распределяться динамически?


person ManRow    schedule 28.02.2011    source источник


Ответы (2)


Если у вас есть компилятор, соответствующий C99, вы можете использовать P99 для инициализации. :

static pthread_mutex_t mutexes[NUM_THREADS] =
  { P99_DUPL(NUM_THREADS, PTHREAD_MUTEX_INITIALIZER) };

Это просто повторяет последовательность токенов PTHREAD_MUTEX_INITIALIZER, запрошенное количество раз.

Чтобы это работало, вам нужно только убедиться, что NUM_THREADS расширяется не до переменной, а до десятичной целочисленной константы, которая видна препроцессору и не слишком велика.

person Jens Gustedt    schedule 28.02.2011

Нет, вам не нужно создавать их динамически. Вы можете использовать статический массив, вам просто нужно настроить их все, прежде чем использовать. Ты можешь сделать:

#define NUM_THREADS 5
static pthread_mutex_t mutexes[NUM_THREADS] = {
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER
};

который подвержен ошибкам, если вы когда-либо меняете NUM_THREADS, хотя это можно исправить с помощью чего-то вроде:

static pthread_mutex_t mutexes[] = {
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER
};
#define NUM_THREADS (sizeof(mutexes)/sizeof(*mutexes))

Кроме того, вы можете сделать это с помощью кода, например:

#define NUM_THREADS 5
static pthread_mutex_t mutexes[NUM_THREADS];

// Other stuff

int main (void) {
    for (int i = 0; i < NUM_THREADS; i++)
        pthread_mutex_init(&mutexes[i], NULL);
    // Now you can use them safely.

    return 0;
}

Во всех этих случаях они правильно настроены, прежде чем пытаться их использовать. На самом деле, я бы сделал это задолго до того, как вы приступите к любому многопоточному процессу, но это просто я параноик.

person paxdiablo    schedule 28.02.2011
comment
В первом примере использование NUM_THREADS необязательно. Это может помочь вам поймать определенные ошибки, а также совершить некоторые другие. - person rlibby; 28.02.2011
comment
вы также можете использовать BOOST_PP_ENUM, так как для этого требуется только препроцессор c99 - person Anycorn; 28.02.2011