Reference 关于将OpenSSL与pthreads一起使用的教程

Reference 关于将OpenSSL与pthreads一起使用的教程,reference,pthreads,openssl,Reference,Pthreads,Openssl,声明它可以安全地用于多线程应用程序,前提是至少设置了两个回调函数:locking_function和threadid_func 我已经编写了使用OpenSSL API的程序。此外,我知道如何使用pthreads。然而,OpenSSL文档是以手册的形式编写的,我看不到在多线程应用程序中使用OpenSSL时需要做什么的分步指南 有关于使用OpenSSL和pthreads的教程吗?(我在网上搜索,但没有找到令人满意的结果。) PS:我在Debian Lenny和Ubuntu Lucid/Maveric

声明它可以安全地用于多线程应用程序,前提是至少设置了两个回调函数:locking_function和threadid_func

我已经编写了使用OpenSSL API的程序。此外,我知道如何使用pthreads。然而,OpenSSL文档是以手册的形式编写的,我看不到在多线程应用程序中使用OpenSSL时需要做什么的分步指南

有关于使用OpenSSL和pthreads的教程吗?(我在网上搜索,但没有找到令人满意的结果。)

PS:我在Debian Lenny和Ubuntu Lucid/Maverick工作


PS2:OpenSSL包含一个示例,但它太复杂了,无法开始。

不知道教程,但下面是两个基于libcurl的示例,可能会有所帮助:


本书第10章包括一节使用OpenSSL进行线程安全编程(第255-259页)。本节详细介绍OpenSSL和pthreads库是如何工作的。特别是,它告诉我们如何在静态分配(线程数量是已知的)和动态分配(线程是动态创建和销毁的)中设置回调函数

另一个好的来源是本书的第4.1节,标题为多线程支持。它分别在第4.1.1和4.1.2小节中提供了静态/动态分配机制

最后,还有这本书,这是迄今为止关于这个主题最全面的一本。不幸的是,这本德语书的英文译本不可用

编辑:正如OpenSSL 1.1.0所解释的那样,上述参考现在被认为是过时的:

OpenSSL现在使用新的线程API在多线程环境中使用OpenSSL不再需要设置锁定回调。有两种受支持的线程模型:pthreads和windows threads。还可以在编译时为“无线程”配置OpenSSL。旧的线程API不应再使用。这些函数已替换为“无操作”兼容宏

[亚历山德罗·盖迪尼,马特·卡斯韦尔]

OpenSSL博客文章对此作了进一步阐述

另请参见自2017年起开放的
  • openssl必须配置线程选项
    /config thread-D_REENTRANT

  • 这是一个复制粘贴的问题;openssl tar ball在文件
    crypto/threads/mttest.c


  • 复制相关的特定于平台的实现,调用线程设置进行初始化,调用线程清理进行总结

    根据Wodin使用cURL引用的回答,我所做的就是复制这4个函数

    #include <openssl/crypto.h> //In addition to other ssl headers
    

    通过
    SSL\u load\u error\u strings()消除了所有奇怪的错误SEGFULTS和glibc提供的双重自由条件。

    非常感谢。这是最好的答案,伊姆霍。所有其他答案均参考注明日期的方法。对我来说,我用运行的OpenSSL版本检查了
    OpenSSL版本-a
    。然后,我用git标记引用了确切的版本,在我的例子中,它是
    https://github.com/openssl/openssl/blob/OpenSSL_1_0_1/crypto/threads/mttest.c
    。当使用此方法检查OpenSSL版本时,您可以看到它是否也使用
    -D_可重入
    编译。希望这有帮助。谢谢你+1。我已经根据您的回答详细阐述了我的答案:)为什么不在openssl或libcurl api中添加一个函数init/clean用于多线程?我在web上搜索了一下,发现下面的代码-不幸的是,我对openssl了解不够,无法告诉您它会有帮助,但它似乎与您的问题相关:)好的luckGreat示例!在“lock\u callback”中,我们可以使用读写器锁而不是互斥锁吗?OpenSSL支持吗?@manpatha-是的,回调会向lock函数发送加密写入或加密读取,因此在理论上,您可以使用它来确定需要什么类型的锁。
    /* we have this global to let the callback get easy access to it */ 
    static pthread_mutex_t *lockarray;
    
    static void lock_callback(int mode, int type, char *file, int line)
    {
      (void)file;
      (void)line;
      if (mode & CRYPTO_LOCK) {
        pthread_mutex_lock(&(lockarray[type]));
      }
      else {
        pthread_mutex_unlock(&(lockarray[type]));
      }
    }
    
    static unsigned long thread_id(void)
    {
      unsigned long ret;
    
      ret=(unsigned long)pthread_self();
      return(ret);
    }
    
    static void init_locks(void)
    {
      int i;
    
      lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
                                            sizeof(pthread_mutex_t));
      for (i=0; i<CRYPTO_num_locks(); i++) {
        pthread_mutex_init(&(lockarray[i]),NULL);
      }
    
      CRYPTO_set_id_callback((unsigned long (*)())thread_id);
      CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))lock_callback);
    }
    
    static void kill_locks(void)
    {
      int i;
    
      CRYPTO_set_locking_callback(NULL);
      for (i=0; i<CRYPTO_num_locks(); i++)
        pthread_mutex_destroy(&(lockarray[i]));
    
      OPENSSL_free(lockarray);
    }
    
    int main(int argc, char **argv)
    {
       //pthread initialization goes here
    
      init_locks();
    
      //pthread stuff here (create, join, etc)
    
    
      kill_locks();
      return 0;
    }