как разделить блокировку мьютекса для группы pthreads? - PullRequest
1 голос
/ 14 ноября 2011

Я пытаюсь кое-что сделать с помощью pthreads и синхронизировать их:Как я могу использовать мьютекс только для группы потоков?Допустим, у меня есть t0, t1, t2, .. t20.pthreads работает одновременно, и я хочу иметь блокировку для потоков четных чисел и другую блокировку потоков нечетных чисел ... или одну блокировку для первых десяти, а другую для остальных или одну блокировкудля каждого.Я имею в виду группирование pthreads в зависимости от его данных (четвертый аргумент в этой функции:

int pthread_create (pthread_t * thread, pthread_attr_t * attr, void * (* start_routine) (void *), void *)arg);

и разделяю мьютекс для группы pthreads.

Я работаю над неким банковским проектом и хочу заблокировать все phreads, пытающиеся получить доступ ктот же номер счета. (как в критическом разделе операций CRUD) Имеет ли это смысл ?или есть лучший подход для этого?Заранее спасибо за помощь и время;)

J.

Ответы [ 3 ]

3 голосов
/ 14 ноября 2011

Семафоры взаимного исключения не предназначены для привязки к конкретным потокам, они предназначены для защиты определенных ресурсов.

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

Более действенный подход можетсохранить список учетных записей, над которыми в данный момент работают, в памяти и использовать одиночный utex для защиты.Затем операции блокируют мьютекс, проверяют и, возможно, изменяют список, затем разблокируют мьютекс.

Лучший подход, который вы ищете, - это использовать резервное хранилище типа ACID (например, базу данных) дляубедитесь, что все обновления являются атомарными.

0 голосов
/ 14 ноября 2011

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

В вашем случае это означает один мьютекс на банковский счет.

Следующая проблема заключается в том, что некоторые вещи должны иметь доступ к нескольким структурам данных. Примером этого может быть перевод $ 100 с одного счета на другой (где вы хотите заблокировать обе учетные записи, затем уменьшить баланс первой учетной записи и увеличить баланс второй учетной записи, а затем снять обе блокировки). Это может привести к тупикам. Например, если один поток хочет заблокировать A, то B, а другой поток хочет заблокировать B, тогда A; тогда первый поток может заблокировать A, а второй поток может заблокировать B, и тогда ни один из потоков не сможет получить вторую нужную блокировку.

Решение этой проблемы состоит в том, чтобы иметь глобальный «порядок блокировки» и получать блокировки только в этом порядке.

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

0 голосов
/ 14 ноября 2011

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

Сказав это, правильный способ использованиямьютекс обычно связывает его с заданным набором данных , а не с конкретным набором кода.В случае номера учетной записи вы можете создать один мьютекс для каждого объекта учетной записи и убедиться, что любой поток, который обращается к учетной записи, сначала блокирует соответствующий мьютекс (и разблокирует его, когда это будет сделано).

...