Передача указателя this
на потоки сама по себе не является плохой.То, что вы делаете с ним, может быть.
Указатель this
такой же, как и любой другой тип данных POD-ish.Это просто кусок битов.Однако материал, который находится в this
, может быть больше, чем POD, и передача того, что фактически является указателем на его члены, может быть опасной по всем обычным причинам.Каждый раз, когда вы делитесь чем-либо между потоками, это создает потенциальные условия гонки и тупики.Элементарным средством разрешения этих конфликтов является, конечно, введение синхронизации в форме мьютексов, семафоров и т. Д., Но это может иметь удивительный эффект от сериализации вашего приложения.
Скажем, у вас есть один поток, считывающий данные из сокета и сохраняющий их в синхронизированном буфере команд, и другой поток, который читает из этого буфера команд.Оба потока используют один и тот же мьютекс, который защищает буфер.Все хорошо, верно?
Ну, может и нет.Ваши потоки могут стать сериализованными, если вы не очень осторожны с тем, как блокировать буфер.Предположительно, вы создали отдельные потоки для кодов вставки и удаления буфера, чтобы они могли работать параллельно.Но если вы блокируете буфер с каждой вставкой и каждым удалением, то одновременно может выполняться только одна из этих операций.Пока вы записываете в буфер, вы не можете читать из него и наоборот.
Вы можете попытаться отрегулировать блокировки так, чтобы они были максимально короткими, но при условии, что у вас естьВы можете получить некоторую степень сериализации совместно используемых синхронизированных данных.
Другой подход заключается в явной передаче данных другому потоку и удалении как можно большего объема данных.Например, вместо записи в буфер и чтения из буфера, как показано выше, код сокета может создать какой-то объект Command
в куче (например, Command* cmd = new Command(...);
) и передать его другому потоку.(Один из способов сделать это в Windows - через механизм QueueUserAPC ).
Есть плюсы и минусы для обоих подходов.Преимущество метода синхронизации состоит в том, что он несколько проще для понимания и реализации на поверхности, но потенциальный недостаток состоит в том, что его гораздо сложнее отлаживать, если вы что-то напутаете.Метод переключения может сделать многие проблемы, присущие синхронизации, невозможными (тем самым фактически делая ее проще ), но для выделения памяти в куче требуется время.