使用OpenMP和OpenSSL时内存泄漏和seg故障

我有一个庞大的代码(我的学校项目),我使用Openssl 。 一切都工作完美,工具我决定我会multithreading。 我选择openmp作为我的线程环境,因为它非常简单易学(至少我需要的基础很简单)。

我的整个代码看起来像这样:

 struct mystr[10]; omp_set_num_threads(10); #pragma omp parallel { mystr[omp_get_thread_num()] = call_fun_which_uses_openssl(); } CRYPTO_cleanup_all_ex_data(); 

我的call_fun_which_uses_openssl函数使用低级openssls api函数( MD4((unsigned char*)&string, strlen(string), (unsigned char*)&digest);而不是MD4_CTX ctx等)。 我的函数使用RSA,DSA,…并且无法访问任何全局变量,它使用的每个变量都在call_fun_which_uses_openssl声明,所以像我这样做multithreading应该保证这些变量保持私有。 虽然,我有时会在此代码中出现seg错误。 我读到CRYPTO_cleanup_all_ex_data不是线程安全的(但我需要它因为内存泄漏)但是我在并行区域外使用它,对吧? 当我删除openmp调用时,每次都有效,所以multithreading和openssl一定存在问题。 任何想法如何解决?

在我看来它应该工作,因为call_fun_which_uses_openssl的线程调用为每个线程创建自己的私有变量,应该没有问题…请,帮助:)

看一下OpenSSL源代码树中的openssl/crypto/threads/mttest.c示例。 基本上,您必须提供两个回调函数:

  • 一个实现锁定和解锁的
  • 一个返回唯一线程ID的。

两者都可以使用OpenMP轻松实现:

 omp_lock_t *locks; // Locking callback void openmp_locking_callback(int mode, int type, char *file, int line) { if (mode & CRYPTO_LOCK) { omp_set_lock(&locks[type]); } else { omp_unset_lock(&locks[type]); } } // Thread ID callback unsigned long openmp_thread_id(void) { return (unsigned long)omp_get_thread_num(); } 

在开始之前,必须初始化锁并设置回调:

 void openmp_thread_setup(void) { int i; locks = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(omp_lock_t)); for (i=0; i 

你应该在你的程序中在第一个并行区域之前的某个地方调用openmp_thread_cleanup()一次,你应该在最后一个并行区域之后调用openmp_thread_cleanup()一次:

 // Program start openmp_thread_setup(); #pragma omp parallel { // Parallel OpenSSL calls are now data race free } #pragma omp parallel { // Parallel OpenSSL calls are now data race free } #pragma omp parallel { // Parallel OpenSSL calls are now data race free } openmp_thread_cleanup(); // Program should end now