2010-11-22 3 views
1

Я совершенно новичок в pthreads, и, похоже, много ненужной информации обо всех сайтах, на которых я смотрел.Использование pthreads по двум функциям в C

У меня есть две функции, давайте просто назовем их X и Y на данный момент, они оба работают над блоками в памяти. Если один поток запущен X, я не хочу, чтобы другие потоки вызывали X или Y в одном блоке, как я могу убедиться, что этого никогда не произойдет?

Нужно ли мне блокировать функции mutex для определенных значений блоков?

ответ

0

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

struct block { 
    void *data; 
    size_t len; 
}; 

Вы бы защитить блок, добавив переменную мьютекса в этой структуре:

struct block { 
    void *data; 
    size_t len; 
    pthread_mutex_t lock; 
}; 

Затем необходимо обновить функцию инициализации для этой структуры инициализируется замок:

struct block *new_block(size_t len) 
{ 
    struct block *b = malloc(sizeof *b); 
    b->data = malloc(len); 
    b->len = len; 

    pthread_mutex_init(&b->lock, NULL); 

    return b; 
} 

Х и функции Y (и любой другая функция, которая считывает или записывает в блок), то необходимо взять замок и выпустить его на выходе:

int x(struct block *b) 
{ 
    int retval; 

    pthread_mutex_lock(&b->lock); 

    /* code */ 

    pthread_mutex_unlock(&b->lock); 
    return retval; 
} 

int y(struct block *b) 
{ 
    int retval; 

    pthread_mutex_lock(&b->lock); 

    /* code */ 

    pthread_mutex_unlock(&b->lock); 
    return retval; 
} 

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

2

Вам нужно будет использовать мьютексы.

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

Мьютекс - это тип, определенный pthread.h, pthread_mutex_t. Предусмотрены функции блокировки и разблокировки мьютекса. Эти функции гарантируют, что только один поток может получить блокировку за раз (если вы просто использовали переменную, чтобы указать, что ваш блок используется, у вас будут проблемы параллелизма с этой переменной вместо блока).

В Интернете доступно множество обучающих программ. Google "pthread учебник", и вы должны найти достаточно, чтобы начать работу.

+0

Спасибо за ваш ответ. Так что мне просто нужно сохранить значение вместе с блоком, который показывает, если он читается/записывается (функция X & Y)? (Я новичок в мьютексах)? – Alex

+1

@Alex Вам просто нужно вызвать pthread_mutex_lock (mutex), он не вернется, пока мьютекс не станет свободным. – Ben

+1

Вы можете либо иметь значение «pthread_mutex_t» в каждом блоке, либо создать сопоставление от 1 до 1 между блоками памяти и таблицей блокировок. Вы действительно должны стараться избегать разных потоков, требующих доступа к одной и той же памяти, хотя, потому что вы не хотите, чтобы потоки тратили много времени на блокировки. – nategoose

1

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

Первый способ проще реализовать - просто все или ничего подход для всей функции X или Y.

+0

Спасибо за ваш ответ. Так что мне просто нужно сохранить значение вместе с блоком, который показывает, если он читается/записывается (функция X & Y)? – Alex

0

Многопоточное программирование действительно лучше разрешено с использованием языков более высокого уровня. Некоторые вещи трудно понять в C, и, на мой взгляд, mutli-threading является одним из них. Я нашел, что Java дала мне лучшее представление о проблемах и проблемах. Это легче понять понятия и легче читать документацию. Рамка C++, такая как Poco или Qt, также будет лучше, если Java не ваша вещь.

Как уже говорилось, концептуально вы хотите заблокировать ресурсы (в вашем случае раздел памяти). Семафоры, как концепция, подходят этой проблеме гораздо лучше, чем мьютекс.Я бы изучал семафоры и думал о мьютексах как о строительном блоке семафоров. Если вы спросите меня, мьютекс - это двоичный семафор с плохой идентификацией.