Как правильно сделать многопоточность в C ++? - PullRequest
4 голосов
/ 05 февраля 2010

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

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

Теперь я впервые делаю потоки в C / C ++, и я бы хотел, так сказать, по книгам. У меня есть две проблемы.

  1. Как мне создать эти темы? Это языковой вопрос больше всего на свете.
  2. Как максимально эффективно реализовать саму блокировку? Я полагаю, что если есть конфликт, то запрашивающий поток разместит себя в строке и будет ждать освобождения ресурса. Тем не менее, как я могу реализовать это пробуждение? Я могу сделать цикл опроса области памяти, но это не элегантно. В идеале я считаю, что подход, основанный на прерываниях, был бы лучшим.

Ответы [ 11 ]

0 голосов
/ 06 февраля 2010

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

Похоже, потокобезопасная очередь производителя-потребителя была бы лучшим решением вашей проблемы. Ознакомьтесь с библиотекой Intel Thread Building Blocks (TBB). Я считаю, что многопоточность становится намного проще, когда вы моделируете свою программу, используя парадигму потока данных.

Если вы хотите уменьшить объем памяти больших, разреженных матриц, посмотрите Boost.uBlas . Он имеет шаблонный класс sparce_matrix, который использует карту для ассоциативного хранения элементов по индексам.

По соображениям эффективности вы не захотите передавать целые матрицы путем копирования в свою очередь производителя-потребителя. Вместо этого вы захотите обойти прокси своих разреженных матриц. Если у TBB еще нет какого-либо прокси-сервера, вы можете просто использовать boost :: shared_ptr. Вы также можете иметь заранее выделенный пул матриц, которые перерабатываются в «схеме» потока данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...