Использование OpenSSL в многопоточном приложении
================================================

Я писал клиентское приложение SOAP на C ++ в Ubuntu, используя OpenSSL для моего транспорта HTTPS и pthreads для потоков. У меня есть несколько потоков - один центральный поток сбора данных, который периодически получает рабочие потоки для выполнения запросов SOAP через общие очереди, защищенные мьютексами.

Читая документацию по OpenSSL я нашел[OpenSSL поточно-ориентирован?](https://www.openssl.org/support/faq.html#PROG1) в FAQ по OpenSSL, в котором описаны механизмы, необходимые для обеспечения безопасности потоков при использовании OpenSSL. Я реализовал это, и все работает отлично.

Причиной моего вопроса на самом деле является концептуальная трудность. Я думал о реализации той же функциональности, что и мое приложение, но вместо использования потоков я бы создал 2 отдельных**applications** Один для рабочего потока (из которых будет запущено несколько копий), а другой для основного потока сбора данных. Затем я бы использовал TCP-сокеты для связи между двумя, а не мьютекс-защищенными очередями. Это может быть плохой идеей, но это не очень важно - меня смущает то, что**would I have to implement the same functions required to ensure OpenSSL thread safety in this second approach or not?**

Я предполагаю, что мне это не нужно, и они могут рассматриваться как независимые (действительно, наверняка, так должно быть, так как многие приложения используют OpenSSL), но в чем причина этого?**What is different between multiple applications using shared library code and multiple threads sharing the same code??**  Уже несколько лет я успешно пишу многопоточные приложения, и меня беспокоит, что я не могу найти ответ на этот вопрос.

Разница в том, что когда несколькоthreads совместно используют один и тот же код библиотеки, они также используют одни и те же глобальные структуры данных; когда несколько процессов совместно используют этот библиотечный код, они не получают.

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

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



Я думаю, главное отличие в том, что в**multiple threads sharing the same code**при необходимости можно выполнить синхронизацию, тогда как в**multiple applications using shared library code** это не легко возможно, кроме как с такими механизмами, как блокировка файлов. Кроме того, будет значительный прирост производительности.

Рассмотрим, например, приложение, которое содержит**display(msg)** метод, который просто пишет на экран, и main (), который вызывает display (msg). Если есть**five threads** вызывая этот метод, мы сможем синхронизировать вызовы, чтобы вывод не искажался. Однако, если метод отображения (MSG) был реализован в**five different applications** и TCP-сокеты использовались для отправки сообщения из основного приложения, вывод будет искажен.

Так что в вашей ситуации это зависит от того, что рабочие потоки пытаются сделать с OpenSSL. Насколько я понимаю, они устанавливают отдельные SSL-соединения, поэтому в приложении не требуется безопасность потоков. Но это приведет к снижению производительности, так как простой вызов функции преобразуется в связь по протоколу TCP между двумя приложениями, и я думаю, что связанные с этим издержки будут намного больше, чем преимущество однопоточных приложений.