       

     13 

          - . 
,   -    ,  
 SetWindow~\'\rordH'~5etWmdowLong.    
(thread-local storage, TLS)        
(,      )       
    . 
    TLS      .     
   ,       
     .     
strtok.            
  .     strtok  
  NULL,    ,    . 
         :    strtok, 
,      ,      .  
         , 
 .     ,  strtok,  
 ,  .    ,   
 . 
       ,      
    :     
  ,   strtok.   
    asctime  gmtime  . 
          ,    
,        
 .  ,      
     ^" (  ) 
      .  :  
         . 
              ,  
.     ,         
   .      ,  
,      strtok  .   
     ,      
           . 
    '~~     .    
    ,   
    ,     ,   
.   

    395 

    396 _____________________________Windows   

    ,        ; ,  
     . 
       TLS-,    ,    
,    DLL,       DLL,   
       ,     
.     ,   ,   
    .     - .  
 DLL    .   ,     
  .  ,    ,  
  . 

        

          ,  
  4 . ,     DLL-,   -. 
     . 13-1    ,   
    Microsoft Windows 95  Microsoft Windows NT. 

    I  I 
      TLS    (TLS_MINIMUM_AVAILABLE - 1) 
    I I I I I I U---I 
    '  i  1 , i  1 i^-, 
    /V 
    I'rft ,;                                          
    ;";,:  1                                  0     1 
    lllslltSj  2                                  0     2 
         3                                  0     3 
    yji.S';-:;?!  4                                  0     4 
    1.3_11_11.1--2    ~0|  TLS_MINIMUM_A VAILABLE - 2 
     TLS_MtNlMUM_AVA4A6LE - 1       0 |  TLS_MINIMUM_AVA1LABLE - 1 

    . 13-1.   ,    
   

              
FREE  INUSE,   ,      
   (TLS-). Microsoft ,    
 TLS_MINIMUM_A VAILABLE       
Win32-aopax. (,  TLS_MINIMUM_A VAILABLE   
 WINNT.H  64.)        
        DLL. 
       TLS-,    
TbAlloc. DWORD TlsAlloc(VOID); 

    _________________________ 13.    397 

              
  FREE. ,     INUSE, a TIsAlloc  
    . DLL ( )    
   '.      FREE, TIsAlloc 
  TLS_OUT_OF_INDEXES (   WINBASE.H  OxFFFFFFFF). 
     TIsAlloc  ,  ,     FREE, 
     INUSE, a TIsAlloc  0.  99% ,  
 TIsAlloc.   1%   . 
     ,      TLS_MINIMUM_AVAILABLE 
  32-   EPVOID;      
  .   (    
 32- )    (. . 13-1). 
       -  LPVOID- , ,  
   ,        TIsAlloc. 
   -   . ,  
 3,       LPVOID-   
       ,   ,    , 
     . 
         ,   TIsSetValue: 

    BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID IpvTIsValue): 

        ,     
dwTlsIndex,   LPVOID (   32- ), 
   IpvTIsValue.  IpvTIsValue   
,  TIsSetValue.     TRUE. 
      TIsSetValue,     LPVOID-.   
 -      .     
  TLS-,       
    ,   .    
 -        32- 
  CreateThread  _beginthreadex~'Te      
  . 
     TIsSetValue,        
,     TIsAlloc.    
  , Microsoft    .   
 ,    TIsAlloc,    
     32- ,    . 
            TIsGetValue: 

    LPVOID TlsGetValue(DWORD dwTlsIndex); 

      ,   TLS-   
dwTlsIndex.   TIsSetValue,  TIsGetValue    
,    .     
  . 
       TLS-      , 
 TIsFrep. 

    BOOL TlsFree(DWORD dwTlsIndex); 

        ,      . 
 INUSE,     ,   
FREE,   ,      TIsAlloc,    
  . TIsFree  TRUE,   .  
  TLS-  . 
    1.     ,      
 ,            
   . 

    398 _____________________________Windows   


         

    ,   DLL   TLS-,  DllMain  
 DLL_PROCESS_ATTACH  DLL   TIsAlloc,   
 DLL_PROCESS_DETACH   TIsFree.  TIsSetValue  TIsGetValue 
      ,   DLL. 
          TLS-:      
. ,  DLL   ,   
strtok.           
40- ,   ,      
 .     , , : 

    DWORD g_dwTlsIndex; // ,     
    //     TIsAlloc 
    void MyFunction(LPSOMESTRUCT IpSomeStruct) { if (IpSomeStruct != NULL) { 
    //      -  
    // ,          
    if (TlsGetVaiue(g_dwTlsIndex) == NULL) { 
    //   ;      
    TlsSetValue(g_dwTlsIndex, HeapAlloc(GetProcessHeap(), 0, 
    sizeof(*lpSomeStruct)); 
    } 
    //   ;      
    memcpy(TlsGetValue(g_dwTlsIndex), IpSomeStruct, sizeof(IpSomeStruct)); 
    } else { 
    //      ; 
    '//     - 
    //     
    IpSomeStruct = (LPSOMESTRUCT) TlsGetValue(g_dwTlsIndex); 
    //     IpSomeStruct;   
    } 
    } 

          MyFunction,     
   . 
      ,  64 ( ) TLS-   , 
:      DLL.  , 
, 10 TLS-,   5  . .        
,   ,  DLL    
TLS-.       ,    
 MyFunction. ,    40-   10 
TLS-,       

    _________________________ 13.    399 

     TLS-,      .  
      ,    
   TLS,       MyFunction. 
         ,     
,  TIsAlloc.   : 

    DWORD dwTlsIndex; 
    LPVOID IpvSomeValue; 
    dwTlsIndex = TIsAllocO; 
    TlsSetValue(dwTlsIndex, (LPVOID) 12345); 
    TIsFree(dwTlsIndex); 
    // ,  dwTlsIndex,     TIsAlloc, 
    //  ,     TIsAlloc 
    dwTlsIndex = TlsAlloc(); 
    IpvSomeValue = TlsSetValue(dwTlsIndex); 

      ,    IpvSomeValue    ? 
12345?  0.    , TIsAlloc    
     0        
 .  !   ,    
LoadLibrary,   DLL,   TIsAlloc,   
- .      FreeLibrary   PLL. 
     ,  TIsFree,   
,    DLL      TLS-?   
    LoadLibrary    DLL,  
   TIsAlloc     ,    DLL.  
  TIsAlhc   ,       ,   
    ,      . 
    , DLL,  ,  ,   
-   ,   TIsGetValue,    
 .   TIsAlloc       
 ,           DLL. 
     .    MyFunction,      
,     ,       
     , ,   MyFunction,   
 .    .  , TIsAlloc 
  ,    . 

    - TLSDyn 

     TLSDyn (TLSDYN. EXE) (.   . 13-2) , 
      .  
   SOMELIB.DLL (.   . 13-3). , 
  DLL_PROCESS_ATTACH,   TLS-,  
  DLL_PROCESS_DETACH,   .  
     TLSDyn  SOMELIB.DLL    TLSDYN 
 -,   . 
    SOMELIB.DLL   LoadResString.     ( 
TIsGetValue) ,        :  
 NULL, 

    400 _____________________________Windows   

    ,   LoadResString .   LoadResString  
    ,     TLS-  . 
       ,        
LoadResString,      ,    
 .  LoadResString  LoadString     
     DLL  .     
 . 
    , , LoadResString    ( 
 nStringId)       .  
,  LoadResString,     DLL - . 
      ,    TLSDyn.     
  : 

     
    String *0 
    [ 

     ,  WinMain   LoadResString, 
    DLL   String #0   
     .      
MessageBox  ,    . 
              5 
.     LoadResString      . 
     ( 4 ).      
 ,         String #. 
       .    
  ,    : 

    Execution log: 
    Thread iH: String #13 
    ! Thread 2: String #2 
    e Thread *3: String f3                    !! t 
    , Thread #4: String #4                     ; i 
    I Thread 5: String 5                    -Is'! 
    A Thread*): String #1                     ?1";' 
    ^Thread!: String f\                     I'::-
    (: Thread tfZ: String 2                    ?; ,| 
     Thread!: String 1                     I I 
    1 Thread 3: String f3                    S ?1 
     Thread #4: String 4                    ;S|; 
     Thread 2: String 2                      ':' 
    si Thread 5: String 5                      ? 
    I Thread f3: String f3                    ;1 ? 
    :'! Thread #2: String S2                     ;? I 
    Thread M: String 4                   1 ' 
    Thread #3: String                    ;'! 
    ;:; Thread 5: String #5                   J 
     Thread #4: String 4 
    iJThreadNl^tnna5      ..^^- -51  

           .    
,  LoadResString      .  
   ,   -        
 ,        .     
  DllMain   ,     
DLL_PROCESS_ATTACH  DLL_PROCESS_DETACH,    ,    
      ,   

    _________________________ 13.    401 

    ,          LoadResString.   
,   SOMELIB.DLL,  .   
     : 
          LoadResString  WinMain.  
LoadResString      ,   
String #0. 
    ,  DllMain ( SOMELIB.DLL)    , 
  DLL_THREAD_DETACH  DLL_PROCESS_DETACH.    
DLL ,        , ,  , 
 .         
 TLSDyn,    .    :  
   (,    DllMain).     ,  
 TIsFree ( DllMain     DLL  ). 
     ,    ,       
 LoadLibrary,  SOMELIB.DLL. DllMain   
 TLS-,         
,   .  -    LoadResString, 
   ,  -    FreeLibrary,  
  SOMELIB.DLL. DllMain   
DLL_PROCESS_DETACH    ,    . 
    ?     (  ) 
LoadResString.       ,   
     . 
    ,     - .  DLL   
     - ;  DLL  
 DLL_PROCESS_DETACH,        
     HeapFree. 

    TLSDYN.C 
    /...****,....***.***.,*******.*.*.*****......*.***.,.....*.****.,.****.*., 
    : TLSDyn, 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    ...*.***.*..,,.,*.*...,.****.....,**.*.*,.....*...*,..,.,***.,.*..*.,.******./ 
    ftinclude ".,\CmnHdr,H"           /* .   */ 
    ftinclude <windows.h> 
    ^include <windowsx.h> 
    ffinclude <tchar.h> 
    ftinclude <stdio.h>               //  sprintf 
    ftinclude <process.h>             //  _beginthreadex 
    ftinclude "..\SomeLib\SomeLib.H" 
    einclude "Resource.H" 

    . . . 

    . 13-2.   TLSDyn 

    402 ______________________________ Windows   


    . 13-2  () 

    1111111111111111111/1111111//1111111/11111/1111111111/1111111111111111111111111 
    HWND g_hwndLog = NULL; 
    /////////////////////////////////////////////
    DWORD WINAPI ThreadFunc (LPVOID IpvThreadParm) { 
    int nThreadNum = (int) IpvThreadParm; 
    int nNumCycles = 4: 
    TCHAR szBuf[100]; 
    LPCTSTR szString = LoadResString(); 
    while (nNumCycles--) { 
    _stprintf(szBuf, TEXT( "Thread ff%d: %s"), nThreadNum, szString); 
    ListBox_Add8tring(g_hwndLog, szBuf); 
    Sleep(nThreadNum * 50); 
    \ i 
    return(O); 
    i 
    f 
    ////////////////////////////////////////////
    BOOL Dlg_0nlnit0ialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 
    int nThreadNuffi; 
    //      
    chSETDLGICONS(hwnd, IDI_TLSDYN, IDI_TLSDYN); 
    g_hwndLog = GetDlgItem(hwnd, IDC_LOG); 
    for (nThreadNum = 1; nThreadNum <= 5; nThreadNum++) { 
    HANDLE hThread; 
    DWORD dwIDThread; 
    hThread = chBEGINTHREADEX(NuLL, 0. ThreadFunc, 
    (LPVOID) nThreadNum, 0, &dwIDThread); 
    CloseHandle(hThread); 
    } 
    return(TRUE): 
    ) 
    /////////////////////////////////////////
    void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCti, UINT codeNotify) { 
    switch (id) { 
    case IDCANCEL: 
    EndDialog(hwnd, id); 

    . . . 

    _________________________ 13.    403 


    . 13-2  () 

    break; 
    \ 
    f 
    \ 
    /////////////////////////////////////
    BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 
IParam) { 
    switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd. WM_INITOIALOG, Dlg_OnInitDialog); 
    chHANDLE_DLGMSG(hwnd. WM_COMMAND, Dlg_OnCommand); 
    } 
    return(FALSE); 
    i 
    i 
    /////////////////////////////////////////////////////////////////////////////// 
    int WINAPI _tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) < 
    ChWARNIFUNICODEUNDERlAlIN95(): 
    MessageBox(Nl)LL, LoadResString(), __TEXT( "String Before Dialog Box"), MBJ)K); 
    DialogBox(hinstExe, MAKEINTRESOURCE(IDD_TLSDYN), NULL, Dlg_Proc); 
    MessageBox(NULL, LoadResString(), __TEXT("String After Dialog Box"), MB_OK); 
    return(O); 
    } 
    //////////////////////////////////   I I I I i I I I I H t i I I 
    SOMELIB.C 
    : SomeLib.C 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    ((include ". .\CrnnH(3r. H"           /* .   */ 
    ((include <windows.h> 
    ((include "Resource.h" 
    ((define SOMELIBAPI __declspec(dllexport) 
    ((include "SomeLib.H" 

    . . . 

    . 13-3.  SomeLib.DLL 

    404 _____________________________Windows   


    . 13-3  () 

    ///////////////////////////////////////
    DWORD g_dwTls!ndex = TLS_OUT_OF_INDEXES; 
    HINSTANCE g_hinstDll = NULL; 
    //         
    //  nStringId   LoadResString 
    HANDLE g_hMutex = NULL; 
    ////////////////////////////////////////////////'///////7///7//1'.//////7/7/////'/// 
    BOOL WINAPI DllMain (HINSTANCE hinstDll. DWORD fdwReason, LPVOID IpvReserved) { 
    LPTSTR IpszStr; 
    switch (fdwReason) { 
    case DLL_PROCESS_ATTACH: 
    7/XL     
    //   
    g_hinstDll = hinstDll; 
    
    //        
    g_dwTls!ndex = TIsAllocO; 
    if (g_dwTlsIndex == TLS_OUT_OF_INDEXES) { 
    // TLS-    -  
    // DLL    
    return(FALSE); 
    } 
    g_hMutex = CreateMutex(NULL, FALSE, NULL): 
    if (g_hMutex == NULL) { 
    //     -  
    // DLL    
    return(FALSE); 
    i 
    break; 
    case DLL_THREAD_ATTACH: 
    //      
    break; 
    case DLL_THREAD_DETACH: 
    //    
    // ,  TLS-    
    if (g_dwTlsIndex != TLS_OUT_OF_INDEXES) { 

    . . . 

    _______________________ 13.    405 


    . 13-3  () 

    II      
    IpszStr = TlsGetValue(g_dwTlsIndex); 
    // ,   -  
    //    
    if (IpszStr != NULL) { 
    HeapFree(GetProcessHeap(), 0, IpszStr); 
    } 
    / 
    break; 
    case DLL_PROCESS_DETACH: 
    //    DLL   
    //   
    // ,  TLS-    
    if (g_dwTlsIndex != TLS_OUT_OF_INDEXES) < 
    //       
    IpszStr = TlsGetValue(g_dwTlsIndex); 
    // ,   -  
    //    
    if (IpszStr != NULL) { 
    HeapFree(GetProcessHeap(). 0, IpszStr); 
    } 
    //  TLS- 
    TlsFree(g_dwTlsIndex); 
    } 
    // ,     
    if (g_hMutex != NULL) { 
    CloseHandle(g_nMutex); 
    } 
    break; 
    } 
    return(TRUE); 
    I 
    /////////////////////////////////////////////////////////////////////////////// 
    ftdefine RESSTR_SIZE       (1000 * sizeof(TCHAR)) 
    SOMELIBAPI LPCTSTR LoadResString (void) { 
    static int nStringId = 0; 
    LPTSTR IpszStr = TlsGetValue(g_dwTlsIndex); 

    . . . 

    406 _____________________________ Windows   

    . 13-3  () 

    if (IpszStr == NULL) { 
    IpszStr = HeapAlloc(GetProcessHeap(), 0, RESSTR_SIZE); 
    TlsSetValue(g_dwTlsIndex, IpszStr); 
    } 
    WaitForSingleObject(g_hMutex, INFINITE); 
    LoadString(g_hinstDll, IDS_STRINGFIRST + nStringId, IpszStr, RESSTR_SIZE); 
    nStringId = (nStr-ingId + 1) % IDS_STRINGNUM: 
    ReleaseMutex(g_hMutex); 
    return(lpszStr); 
    i 
    i 
    //////////////////////////////////   I / / I I I I / / / I I///I 
    SOMELIB.H 
    /***.*..*...*******.*.*...**,*****...*.*,,*******^***,*...**.***********.... 
    : SomeLib.H 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    **,.***,******...*********,..,...,,***,*****...*.***,*******...,,..***..**.*/ 
    #if !defined(SOMELIBAPI) 
    ftdefine SOMELIBAPI __declspec(dllexport) 
    ffendif 
    // ,     
    ftdefine IDS_STRINGLAST (IDS_STRINGFIRST + 9) 
    ftdefine IDS_STRINGNUM (IDS_STRINGLAST - \ 
    IDS_STRINGFIRST + 1) 
    // ,      
    SOMELIBAPI LPCTSTR LoadResString (void); 
    ////////////////////////


        

            ,   
,     ,      
    .   TLS   
,         - . 
      :        
,  .        
   : 

    __declspec(thread) DWORD gt_dwStartTime = 0; 

    __________________________ 13.    407 

     _declspec (thread)   ,    
Microsoft Visual C++.   ,    
     -  DLL-. , 
  _declspec (thread),    ,  
  ( ) .     
_declspec (thread)  .         
       . ,  
TLS-    gt_ ,    st_. 
     ,    TLS-   
,     ,      .tis. 
  .tls-        
    .tis,    -  DLL-. 
      TLS       
.    ,    -  
.tis          
TLS-.  ,         
,    ,     
.         
   TLS-,      
   .  ,   86   
  TLS-   3  
 . 
         ,      
      .    
       TLS-    
  TLS-   . 
           TLS-.  ,  
   DLL.     ,  
 TLS-,   - DLL,    
   .   ,   
    .tis,         
 .tls-,   DLL,    .  
      ,  
,      TLS-,   
,       DLL.   ,    ! 
      ! ,  ,    LoadLibrary  
 DLL,    TLS-.   
 ,    ,     
TLS-,       , 
  DLL.      FreeLibrary   DLL 
  TLS-,     , 
      . 
          .  ,  
  DLL,   TLS-,    
    TLS-,    
      . , ,  
  TLS;    TLS   
 . DLL,    TLS,    
          . 

    - TLSStat 

     TLSStat (TLSSTAT.) (.   . 13-4)  
    .     
   

    408 _____________________________Windows   

        TLSSTAT  -,   .  
       ,   
        : 

    Thread number:     1              Clear     i 
     of cycles;      
    Sycle time (sees):   p;I' Create thread 1 
    Thread execution log 
    11                                                                         

         : 

    __declspec(thread) DWORD gt_dwStartTime = 0; 

         gt_dwStartTime.  ,  
    ,      
.       ,      
 . 
      Create Thread ( )     
,       ,   
  ( ,  ,  , 
  ),     . 
     _beginthreadex,     
    .      
  (    ).2 
         ,      
 gt_dwStartTime     .    
      Thread Execution Log (  
)    . 
              gt_dwStartTime, 
    (  )  dwStartTime  
   ThreadFunc.  ,     :   
          
TLS-.          
 TLS-. 
          ,  TLS- 
_11_ DLL,       . 
           (  Num Of 
Cycles)     [  Cycle Time (Sees)]. 
     ,     
 ,  
    2.    ,  ,       
Win32 ,     -   
TLS-,   .   ,   
              
 . 

    _________________________ 13.    409 

     ;       Num Of Cycles  Cycle 
Time (Sees)       Create Thread.  
       3 : 

    Thread number.                   Clear     j 
    Hum ot cycles;      
    Sycle time (sees):   p([""Create !hread"'i| 
    Thread execution loci: 
    Thread 1, Cycles lett=9, time running=0 
    Thread 1, Cycles left=8, time running=3005            : ': 
    Threadl.Cycle lefl-7.time running-6009           '.:, 
    Thread 1. Cycle left-6. time running-9013              ; 
    Thread started: 
    Thread 2, Cycle lett^.tme running=0              ! i: . 
    Thread 2. Cycle lert-3,tme runmng-2003            ,' 
    Threadl.Cycle left-B.tme running-12016           , ^ 
    Thread 2. Cycle left-2. tme running"1006           .,;; 
    Thread started:                                   : , 
    Thread 3. Cycle left=2. tme running=0              ' 
    Thread 1. Cycle left-< tme running-15022 
    Thread 2, Cycle left-1. tme running-6009              . 
    Thread 3, Cycle lett=1,tme running=1001              . 
    Thread 3. Cycle left=0. tme running-2003 
    ,1 Thread 2. Cycle left-0 tme running=S012           _d 
    h___________ 
           : 
    Thread Number          Num Of Cycles          Cycle Time (Sees) 
    ( )           ( )         [  ()] 
    1                        10                        3 
    252 
    3                        3                        1 
     Thread Number      . 
     ,   Clear 
();      1,    . 
     .    TLSStat    : 

    Total time running applicetion-327941.   i 
    era 

        ,   (  
)     TLS- gt_dwStartTime. 
)     TLS- gt_dwStartTime. 


    410 _____________________________Windows   


    TLSSTAT.C 
    /**,****.***,,**,*.**..*..**..**.***,,**.,.*.,,**..********..*****,,*..,,**,.,. 
    : TLSStat.C 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    .*******,**.*****,***.***,,**.***.*.*,**,..***.**...***,****,*.***,.********../ 
    ftinclude "..\CmnHdr.H"           /* .   */ 
    ^include <windows.h> 
    ftinclude <windowsx.h> 
    ftinclude <tchar.h> 
    ftinclude <stdlib.h>              //  rand 
    ftinclude <stdio.h>               //  sprintf 
    ffinclude <process.h>             //  _beginthreadex 
    #include "Resource.H" 
    ///////////////////////
    II           
    typedef struct { 
    int nThreadNum;     //   
    int nNumCycles;     //   
    DWORD dwCycleTime; //   
    } THREADDATA, *LPTHREADDATA; 
    
    //    ,    
    //     
    HWND g_hwndLogLB = NULL: 
    
    //   TLS-    
    //   .      
    //     . 
    __declspec(thread) DWORD gt_dwStartTime = 0: 
    ////////////////////////////////
    DWORD WINAPI ThreadFunc (LPVOID IpvThreadParm) { 
    // ,  , -    THREADDATA; 
    //      
    LPTHREADDATA IpThreadData = (LPTHREADDATA) IpvThreadParm; 
    TCHAR szBuf[100]; 
    //        TLS- 
    gt_dw8tartTime = GetTickCount(); 
    //   ,     
    _stprintf(szBuf, __TEXT("Thread started: %d"), lpThreadData->nThreadNum); 
    ListBox_AddString(g_hwndLogLB, szBuf); 
    ListBox_SetCurSel(g_hwndLogLB, 0); 

    . . . 

    . 13-4.   TLSStat 

    __________________________ 13.    411 


    . 13-4  () 
    
    II  - ... 
    while (lpThreadData->nNumCycles--) { 
    
    //   ,      
    //          
    _stprintf(szBuf, 
    
    __("Thread %d, Cycles left=%d, time running=%d"), 
    lpThreadData->nThreadNurn, lpThreadData->nNumCycles, 
    GetTickCountO - gt_dwStartTime); 
    ListBox_AddString(g_hwndLogLB, szBuf): 
    // ""       
    Sleep(lpThreadData->dwCycleTime): 
    } 
    
    //    ;      
    //        
    _stprintf(szBuf, __TEXT("Thread ended: %d, total tlme=%d"), 
    lpTnreadData->nThreadNum, GetTickCountO - gt_dwStartTime); 
    ListBox_AddString(g_hwndLogLB, szBuf): 
    //      THREADDATA, 
    //    
    HeapFree(GetProcessHeap(), 0, IpvThreadParm); 
    return(O); 
    i 
    /////////////////////////////////
    BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 
    
    //      
    chSETDLGICONS(hwnd, IDI_TLSSTAT, IDI_TLSSTAT); 
    //     - 1 
    SetDlgItemInt(nwnd, IDC_THREADNUM, 1, FALSE); 
    
    //     - 10 
    SetDlgItemInt(hwnd, IDC_NUMCYCLES. 10, FALSE); 
    
    //     - 3  
    SetDlgItemInt(hwnd, IDC_CYCLETIME, 3, FALSE); 
    //       , 
    //           
    g_hwndLogLB = GetDlgItem(hwnd. IDC_LOG): 

    . . . 

    412 ______________________________ Windows   


    . 13-4  () 
    
    II   ,    Create Thread 
    //    
    SetFocus(GetDlgItem(hwnd, IDOK)); 
    
    //   .  Dialog Manager'     
    return(FALSE); 
    ////////////////////////////////////////////    
    void Dlg_OnCommand (HWNO hwnd, int id, HWND hwndCtI, UINT codeNotify) { 
    DWORD        dwIDThread: 
    HANDLE       hThread; 
    LPTHREADDATA IpThreadData; 
    switch (id) { 
    case IDC_CLEAR; 
    
    //     
    Set01gltemlnt(hwnd, IDC_THREADNUM, 1, FALSE): 
    ListBox_ResetContent(g_hwndLogLB): 
    break; 
    case IDOK: 
    
    //   ,      
    //        - , 
    //     
    
    IpThreadData = (LPTHREADDATA) HeapAlloc(GetProcessHeap(), , 
    sizeof(THREADDATA)); 
    if (IpThreadData == NULL) { 
    //    ;   
    chMB(__TEXT("Error creating ThreadOata")); 
    break; 
    //        
    lpThreadData->nThreadNum = 
    GetDlgItemInt(hwnd, IDC_THREADNUM, NULL. FALSE): 
    lpThreadData->nNumCycles = 
    GetDlgItemInt(hwnd, IDC_NUMCYCLES, NULL, FALSE); 
    //     1000. 
    //     
    lpThreadData->dwCycleTime = (DWORD) 
    (1000 * GetDlgItemInt(hwnd, 
    IDC_CYCLETIME. NULL, FALSE)): 

    . . . 

    ________________________ 13.    413 


    . 13-4  () 
    
    II    
    SetDlgItemInt(hwnd, IDC_THREADNUM, lpTnreadData->nThreadNum + 1, FALSE); 
    
    //         
    //   ,  ,   
    //   .      
    // ,    . 
    hThread = chBEGINTnREADEX(NULL. , ThreadFunc, 
    (LPVOID) IpThreadData, 0, &dwIDThread); 
    if (hThread != NULL) { 
    //    ,  ; 
    //         
    CloseHandle(hThread); 
    !^ { 
    //    ;   
    chMB(__TEXT("Error creating the new thread")); 
    HeapFree(GetProcessHeap(), 0, (LPVOID) IpThreadData); 
    } 
    break; 
    case 1DCANCLL: 
    EndDialog(hwnd, id): 
    break: 
    BOOL CALLBACK Dlg_Proc (HWND hwnd. UINT uMsg, WPAHAM wparam, LpAhAM 
ipaiam,) | 
    switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd. WM_INITDIALOG, Dlg_OnImtDialog); 
    chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dig_OnCommand); 
    } return(FALSE); 
    \ 
    int WINAPI _tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) { 
    TCHAR szBuf[100]; 
    chWARNIFUNICODEUNDERWIN95(); 

    . . . 

    414 ______________________________Windows   


    . 13~4   () 

    II        gt_dw8tartTime. 
    //      . 
    gt_dw8tartTime = GetTickCount(): 
    DialogBox(hinstExe, MAKEINTRESOURCE(IOD_TLSSTAT). NULL, Dlg_Proc)' 
    //    : , 
    //     
    _stprintf(szBuf, __TEXT("Total time running application=%d."), 
    GetTickCountO - gt_dwStartTime): 
    chMB(3zBuf); 
    '^+^):