织梦CMS - 轻松建站从此开始!

罗索

pthread 静态编译版本在Windows下使用时的注意事项

jackyhwei 发布于 2011-08-29 11:01 点击:次 
在Windows下使用静态编译的pthread时要特别注意一下,必须显式的调用如下四个函数,否则pthread用到的一些全局变量会没有被初始化,导致所有的pthread的APIs调用都crash.
TAG:

作为通用的跨平台高性能线程库,在很多跨平台的项目中都可以看见pthread的身影。pthread本身的实现比较优雅,APIs使用起来也很方便。

但在Windows下使用静态编译的pthread时要特别注意一下,必须显式的调用如下四个函数,否则pthread用到的一些全局变量会没有被初始化,导致所有的pthread的APIs调用都crash.

BOOL pthread_win32_process_attach_np (void);

BOOL pthread_win32_process_detach_np (void);

BOOL pthread_win32_thread_attach_np (void);

BOOL pthread_win32_thread_detach_np (void);

pthread官方文档对此有如下的明确说明:

These functions contain the code normally run via dllMain when the library is used as a dll but which need to be called explicitly by an application when the library is statically linked.

You will need to call pthread_win32_process_attach_np() before you can call any pthread routines when statically linking.

You should call pthread_win32_process_detach_np() before exiting your application to clean up.

pthread_win32_thread_attach_np() is currently a no-op, but pthread_win32_thread_detach_np() is needed to clean up the implicit pthread handle that is allocated to a Win32 thread if it calls certain pthreads routines. Call this routine when the Win32 thread exits.

These functions invariably return TRUE except for pthread_win32_process_attach_np() which will return FALSE if pthreads-win32 initialisation fails.

通过函数的名字我们不难猜测出如下调用顺序

在程序开始的时候要调用:

BOOL pthread_win32_process_attach_np (void);

BOOL pthread_win32_thread_attach_np (void);

在程序退出时要调用:

BOOL pthread_win32_thread_detach_np (void);

BOOL pthread_win32_process_detach_np (void);

比较通用的做法是在模块Load和UnLoad的时候做这个attach和detach操作,如下面所示:

  1. /* Callback for our DLL so we can initialize pthread */ 
  2.  
  3. BOOL WINAPI DllMain( HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) 
  4. #ifdef PTW32_STATIC_LIB 
  5.     switch( fdwReason ) 
  6.     { 
  7.         case DLL_PROCESS_ATTACH: 
  8.             pthread_win32_process_attach_np(); 
  9.         case DLL_THREAD_ATTACH: 
  10.             pthread_win32_thread_attach_np(); 
  11.             break
  12.         case DLL_THREAD_DETACH: 
  13.             pthread_win32_thread_detach_np(); 
  14.             break
  15.         case DLL_PROCESS_DETACH: 
  16.             pthread_win32_thread_detach_np(); 
  17.             pthread_win32_process_detach_np(); 
  18.             break
  19.     } 
  20. #endif 
  21.     return TRUE; 

注意: PTW32_STATIC_LIB 宏为pthread静态编译的标志,这个可以通过pthread.h的配置或者CFLAGS传递进来。

下面是pthread的官方的dll.c的实现
  1. BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) 
  2.   BOOL result = PTW32_TRUE; 
  3.   switch (fdwReason) 
  4.     { 
  5.     case DLL_PROCESS_ATTACH: 
  6.       result = pthread_win32_process_attach_np (); 
  7.       break
  8.     case DLL_THREAD_ATTACH: 
  9.       /* 
  10.        * A thread is being created 
  11.        */ 
  12.       result = pthread_win32_thread_attach_np (); 
  13.       break
  14.     case DLL_THREAD_DETACH: 
  15.       /* 
  16.        * A thread is exiting cleanly 
  17.        */ 
  18.       result = pthread_win32_thread_detach_np (); 
  19.       break
  20.     case DLL_PROCESS_DETACH: 
  21.       (void) pthread_win32_thread_detach_np (); 
  22.       result = pthread_win32_process_detach_np (); 
  23.       break
  24.     } 
  25.   return (result); 
  26. /* DllMain */ 
也就是说pthread官方代码在动态编译的版本中主动做了这个attach和detach操作。
而静态编译版本由于没有一个合适的地方来做这件事,就将attach和detach的的操作扔给用户来完成了。
上面的代码是针对调用方是Dll的情况做的初始化,如果调用方不是Dll呢?对此可以参照如下做法,虽然很暴力,但很简单,可以工作
1)定义如下函数
  1. #ifdef PTW32_STATIC_LIB  
  2. static void detach_ptw32(void)  
  3. {  
  4.     pthread_win32_thread_detach_np();  
  5.     pthread_win32_process_detach_np();  
  6. }  
  7. #endif  
2)在你的主程序的入口处,一般而言是main()中做如下调用即可
  1. #ifdef PTW32_STATIC_LIB  
  2.     pthread_win32_process_attach_np();  
  3.     pthread_win32_thread_attach_np();  
  4.     atexit(detach_ptw32);  
  5. #endif  
就是用atexit()将detach工作挂接到程序中去,使得程序在退出的时候可以对pthread进行detach.
(psusong)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201108/14914.html]
本文出处:blog.csdn.net/psusong 作者:psusong
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容