我正在进入OpenSSL lib的第一步,感觉有点迷失。我的机器是一个多线程(Xeon系列,如果有人需要信息,可以分享更多)与Linux操作系统。
应用程序构建是SSL代理,因此我需要尽可能快地处理多个TCP流,这意味着我希望尽可能无锁地运行lib。
在crypto/crypto.h
内部看一下主要是关于这一部分:
# ifndef OPENSSL_NO_LOCKING
# ifndef CRYPTO_w_lock
# define CRYPTO_w_lock(type) \
CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
# define CRYPTO_w_unlock(type) \
CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
# define CRYPTO_r_lock(type) \
CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
# define CRYPTO_r_unlock(type) \
CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
# define CRYPTO_add(addr,amount,type) \
CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
# endif
我试图挖掘代码/ API并且有点迷失。我的问题是:
答案 0 :(得分:5)
OpenSSL lib对多核/线程应用程序有什么支持?
支持多线程应用程序,但请注意,它不会只是工作" - 特别是,您必须install some special callbacks以便OpenSSL执行必要的序列化/锁定,否则您的程序将受到竞争条件的影响而无法正常工作。 (即使安装了回调函数,您也希望能够访问限制在单个线程中的任何特定OpenSSL套接字/连接,即不要在同一个连接上执行操作的两个线程的OpenSSL在没有同步的情况下同时处理)
lib的哪些部分只能有一个实例(单例)?
好吧,锁定回调(必然)只有一个实例,因为所有线程都使用它们来序列化关键部分。
此外,SSL库设置函数(SSL_load_error_strings(),SSL_library_init()等)应仅在应用程序执行开始时调用(即在您生成任何线程之前),以及SSL库拆解只有在任何衍生线程加入()后才能调用函数(如果有的话)并丢弃;这样你就可以避免任何可能的竞争条件,即线程试图使用尚未完全构建的OpenSSL资源,或者已被部分或完全破坏。
我希望尽可能无锁地运行lib。
嗯,你可能在那里运气不好 - OpenSSL并没有设计为无锁;其会话使用共享的非只读数据结构,并且必须同步对这些数据结构的访问或发生错误。我认为你能做的最好的事情就是将锁回调用作recommended,并相信OpenSSL实施者不会将锁保持的时间超过严格要求。如果这还不够,那么您可能必须开始寻找不同的SSL库实现,或者考虑使用多进程而不是多线程。