передача "это" в поток с ++ - PullRequest
       13

передача "это" в поток с ++

1 голос
/ 17 октября 2011

Каков наилучший способ выполнения следующего в C ++. Хотя мой текущий метод работает, я не уверен, что это лучший путь:

1) У меня есть мастер-класс, в котором есть какая-то функция

2) У меня есть поток, который принимает некоторые инструкции для сокета, а затем запускает одну из функций в мастер-классе

3) В мастер-классе есть несколько потоков, которые обращаются к различным функциям

Я создаю мастер-класс, а затем создаю экземпляры классов потоков из мастера. Конструктор для класса потока получает указатель «this» для мастера. Затем я могу запускать функции из мастер-класса внутри потоков - то есть я получаю команду для выполнения чего-то, что запускает функцию из мастер-класса из потока. У меня есть мьютекс и т. Д., Чтобы предотвратить проблемы с расой.

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

Ответы [ 3 ]

1 голос
/ 17 октября 2011

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

Указатель this такой же, как и любой другой тип данных POD-ish.Это просто кусок битов.Однако материал, который находится в this, может быть больше, чем POD, и передача того, что фактически является указателем на его члены, может быть опасной по всем обычным причинам.Каждый раз, когда вы делитесь чем-либо между потоками, это создает потенциальные условия гонки и тупики.Элементарным средством разрешения этих конфликтов является, конечно, введение синхронизации в форме мьютексов, семафоров и т. Д., Но это может иметь удивительный эффект от сериализации вашего приложения.

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

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

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

Другой подход заключается в явной передаче данных другому потоку и удалении как можно большего объема данных.Например, вместо записи в буфер и чтения из буфера, как показано выше, код сокета может создать какой-то объект Command в куче (например, Command* cmd = new Command(...);) и передать его другому потоку.(Один из способов сделать это в Windows - через механизм QueueUserAPC ).

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

1 голос
/ 18 октября 2011

Звучит хорошо для меня. На моих серверах он называется «SCB» - ServerControlBlock - и обеспечивает доступ к таким службам, как пулы IOCPbuffer / socket, журнал, доступ к пользовательскому интерфейсу для сообщений о состоянии / ошибках и ко всему остальному, что должно быть общим для всех потоков обработчика. Работает нормально, и я не вижу в этом взлома.

Я создаю SCB (и проверяю в ctor, что все сервисы, к которым он получен доступ, запущен и готов к использованию), прежде чем создавать пул потоков, использующий SCB - никаких неприятных синглетонных вещей.

Rgds, Martin

1 голос
/ 17 октября 2011

Отдельные классы потоков довольно нормальны, особенно если они имеют специфическую функциональность. Я бы не наследовал от основного потока.

...