OpenSSL 和多线程
我一直在阅读有关如果在多用途中使用 OpenSSL 的要求线程应用程序,您必须使用 OpenSSL 注册线程识别函数(以及互斥体创建函数)。
在 Linux 上,根据 OpenSSL 提供的示例,通常通过注册如下函数来标识线程:
static unsigned long id_function(void){
return (unsigned long)pthread_self();
}
pthread_self() 返回 pthread_t,这在 Linux 上有效,因为 pthread_t 只是 unsigned long 的 typedef。
在 Windows pthreads、FreeBSD 和其他操作系统上,pthread_t 是一个结构体,具有以下结构:
struct {
void * p; /* Pointer to actual object */
unsigned int x; /* Extra information - reuse count etc */
}
这不能简单地转换为 unsigned long,当我尝试这样做时,它会抛出编译错误。我尝试采用 void *p 并将其转换为无符号长整型,理论上内存指针应该在线程之间保持一致和唯一,但这只会导致我的程序崩溃很多。
当使用 Windows pthreads 或 FreeBSD 或任何其他类似操作系统时,我可以使用 OpenSSL 注册什么作为线程识别功能?
另外,作为一个附加问题:
有谁知道如果OpenSSL被编译到QT中并与QT一起使用是否也需要这样做,如果是的话如何使用OpenSSL注册QThreads?令人惊讶的是,我似乎无法在QT中找到答案文档。
I've been reading about the requirement that if OpenSSL is used in a multi-threaded application, you have to register a thread identification function (and also a mutex creation function) with OpenSSL.
On Linux, according to the example provided by OpenSSL, a thread is normally identified by registering a function like this:
static unsigned long id_function(void){
return (unsigned long)pthread_self();
}
pthread_self() returns a pthread_t, and this works on Linux since pthread_t is just a typedef of unsigned long.
On Windows pthreads, FreeBSD, and other operating systems, pthread_t is a struct, with the following structure:
struct {
void * p; /* Pointer to actual object */
unsigned int x; /* Extra information - reuse count etc */
}
This can't be simply cast to an unsigned long, and when I try to do so, it throws a compile error. I tried taking the void *p and casting that to an unsigned long, on the theory that the memory pointer should be consistent and unique across threads, but this just causes my program to crash a lot.
What can I register with OpenSSL as the thread identification function when using Windows pthreads or FreeBSD or any of the other operating systems like this?
Also, as an additional question:
Does anyone know if this also needs to be done if OpenSSL is compiled into and used with QT, and if so how to register QThreads with OpenSSL? Surprisingly, I can't seem to find the answer in QT's documentation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我将把这段代码放在这里。它不是万能药,因为它不处理 FreeBSD,但在大多数情况下,当您只需要支持 Windows 和 Debian 时,它会很有帮助。当然,干净的解决方案假设使用最近推出的
CRYPTO_THREADID_*
系列。 (举个例子,它有一个CRYPTO_THREADID_cmp
回调,可以映射到pthread_equal
)I will just put this code here. It is not panacea, as it doesn't deal with FreeBSD, but it is helpful in most cases when all you need is to support Windows and and say Debian. Of course, the clean solution assumes usage of
CRYPTO_THREADID_*
family introduced recently. (to give an idea, it has aCRYPTO_THREADID_cmp
callback, which can be mapped topthread_equal
)我只能回答Qt部分。使用 QThread::currentThreadId(),甚至 QThread::currentThread() 因为指针值应该是唯一的。
I only can answer the Qt part. Use QThread::currentThreadId(), or even QThread::currentThread() as the pointer value should be unique.
从您链接的 OpenSSL 文档中:
如图所示,只有当您可以提供比 OpenSSL 默认实现更好的 ID 时,提供您自己的 ID 才真正有用。
当您不知道 pthread_t 是指针还是整数时,提供 ID 的唯一安全方法是维护自己存储为线程本地值的每线程 ID。
From the OpenSSL doc you linked:
As shown providing your own ID is really only useful if you can provide a better ID than OpenSSL's default implementation.
The only fail-safe way to provide IDs, when you don't know whether
pthread_t
is a pointer or an integer, is to maintain your own per-thread IDs stored as a thread-local value.