精品理论电影在线_日韩视频一区二区_一本色道精品久久一区二区三区_香蕉综合视频

DllMain和多線程死鎖

發布時間:2011-08-29 共3頁

  在Windows操作系統中,DLL(動態鏈接庫)技術有很多優點。例如,多個應用程序可以共享一個DLL文件,真正實現了資源"共享",大大縮小了應用程序的執行代碼,有效地利用了內存,而且DLL文件作為一個單獨的程序模塊,封裝性、獨立性好,有利于提高軟件開發和維護的效率。

  DllMain是可選擇的DLL入口指針,當進程和線程啟動和終止時被系統調用,分別進行創建資源和釋放資源等操作,特別地,也可以在DLL被裝載進進程空間時(即DllMain響應DLL_PROCESS_ATTACH通知時)創建線程,在DLL從進程空間卸載時(即DllMain響應 DLL_PROCESS_DETACH通知時)結束線程。但是,在DllMain中無論是創建線程還是結束線程,都特別要注意一個規則,那就是 DllMain的順序調用規則。

  1、DllMain的順序調用規則

  Windows操作系統中是順序調用DLL的入口函數DllMain的。當進程被創建時,系統也為該進程創建了一個互斥對象。每個進程都有它自己的互斥對象。進程互斥對象的一個作用是,序列化在需要調用DllMain的 4種情況下DllMain的執行:DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH和 DLL_PROCESS_DETACHDLL。DllMain函數的第二個參數指示出調用DllMain的原因。

  在DllMain中創建線程或終止線程時,如果違背了DllMain的這個順序調用規則,程序就會發生死鎖。下面就DllMain中創建線程和終止線程兩種情況下的死鎖分別進行講述。

  2、DllMain中創建和終止線程時的死鎖

  2.1、裝載DLL時創建的線程的為什么沒有運行

  考慮在一個多線程程序中,某個DLL被加載進程地址空間時,該DLL的DllMain啟動了一個線程,然后立即調用一個應答事件對象的 WaitForSingleObject函數,以確認在繼續進行其余的DllMain處理之前,新產生的線程能夠正確地執行一些操作。類似的代碼如下:

  //----------------------start   ------------

  HANDLE       g_thread_handle =NULL;       // 該DLL內部線程的句柄

  DWORD       g_thread_id =0;       // 該DLL內部線程的ID

  HANDLE g_hEvent=NULL;// 應答事件的句柄

  DWORD WINAPI InSideDll_ThreadProc( LPVOID p )

  {

  /* 表示一些操作。

  如果“---- operations.----”被打印到Output窗口中了,

  說明本線程函數在被執行了。 */

  OutputDebugString(“---- operations.---- \n”);

  /*   InSideDll_ThreadProc的操作完成后,

  通知在g_hEvent處等待的線程,可以繼續運行了。*/

  SetEvent(g_hEvent);

  return   1;

  }

  BOOL APIENTRY DllMain( HANDLE hModule,

  DWORD   ul_reason_for_call, LPVOID lpReserved )

  {

  switch (ul_reason_for_call)

  {

  case DLL_PROCESS_ATTACH:

  //DLL正在映射到進程地址空間中

  {

  // 禁止線程庫調用,

  DisableThreadLibraryCalls((HINSTANCE)hModule);

  // 創建DLL內線程使用的事件對象

  g_hEvent = ::CreateEvent( NULL, FALSE, FALSE, _T("hello11" ));

  //創建DLL內線程對象

  g_thread_handle = ::CreateThread(NULL,0,

  InSideDll_ThreadProc,(LPVOID)0,0,   &( g_thread_id) ) ;

  // 等待剛創建的線程完成相關操作

  ::WaitForSingleObject( g_hEvent, INFINITE );

百分百考試網 考試寶典

立即免費試用