2

我一直在 Ubuntu 上用 C++ 编写一个 SOAP 客户端应用程序,使用 OpenSSL 进行 HTTPS 传输,使用 pthreads 进行线程处理。我有许多线程 - 一个中央数据采集线程定期获取工作线程以通过共享互斥保护队列发出 SOAP 请求。

阅读 OpenSSL 的文档,我发现OpenSSL 线程安全吗?在 OpenSSL FAQ 中描述了使用 OpenSSL 时确保线程安全所需的机制。我实现了这一点,一切正常。

我提出问题的原因实际上是一个概念上的困难。我正在考虑实现我的应用程序已经拥有的相同功能,但我将创建 2 个单独的应用程序,而不是使用线程:一个用于工作线程(其中将运行多个副本),另一个用于主数据采集线程。然后,我将使用 TCP 套接字在两者之间进行通信,而不是使用互斥体保护的队列。这可能是一个坏主意,但这并不是很重要 - 让我感到困惑的是,我是否必须在第二种方法中实现确保 OpenSSL 线程安全所需的相同功能?

我的猜测是我不必这样做,它们可以被视为独立的(确实肯定它必须是因为有这么多应用程序使用 OpenSSL)但是它的原因是什么?使用共享库代码的多个应用程序和共享相同代码的多个线程之间有什么不同? 几年来,我一直在成功编写多线程应用程序,我担心我无法回答这个问题。

4

2 回答 2

2

不同的是,当多个线程共享相同的库代码时,它们也共享相同的全局数据结构;当多个进程共享该库代码时,它们不会。

例如,如果 OpenSSL 中的许多加密算法具有可用的大型预计算表,则它们的速度会更快。该表在调用相同 OpenSSL 函数的多个线程之间共享,但必须使用锁定来确保只有一个线程在第一次使用时尝试初始化该表。

再举一个例子,许多 OpenSSL 函数在内部访问随机数生成器,但它的状态是一个全局数据结构,它的访问必须跨线程同步。

于 2012-07-02T07:38:19.777 回答
0

我认为主要区别在于,在共享相同代码的多个线程中,如果需要,可以进行同步,而在使用共享库代码的多个应用程序中,除了文件锁定等机制之外,这是不容易实现的。此外,还会有可观的性能增益。

考虑一个示例应用程序,它包含一个仅写入屏幕的display(msg)方法和一个调用 display(msg) 的 main()。如果有五个线程调用此方法,我们将能够同步调用,这样输出就不会出现乱码。但是,如果 display(msg) 方法在五个不同的应用程序中实现,并且 TCP 套接字用于从主应用程序发送 msg,则输出将出现乱码。

所以在你的情况下,这取决于工作线程试图用 OpenSSL 做什么。据我了解,他们正在建立单独的 SSL 连接,因此在应用程序中不需要线程安全。但是当一个简单的函数调用转换为两个应用程序之间的 TCP 通信时,会有性能开销,而且我认为所产生的开销将远远超过拥有单线程应用程序的好处。

于 2012-06-28T20:50:02.540 回答