3-2

/*
 * TaskQueS.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This is from Chapter 3, Listing 3-2
 *
 * Call ThreadFunc NUM_TASKS times, using
 * no more than THREAD_POOL_SIZE threads.
 * This version uses WaitForSingleObject,
 * which gives a very suboptimal solution.
 *
 * Build command: cl /MD TaskQueS.c
 */

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "MtVerify.h"

DWORD WINAPI ThreadFunc(LPVOID);

#define THREAD_POOL_SIZE 3
#define MAX_THREAD_INDEX THREAD_POOL_SIZE-1
#define NUM_TASKS 6

int main()
{
    HANDLE  hThrds[THREAD_POOL_SIZE];
    int     slot = 0;
    DWORD   threadId;
    int     i;
    DWORD   exitCode;

    /*           i=   1 2 3 4 5 6 7 8 9
     * Start Thread   X X X X X X
     * Wait on thread       X X X X X X
     */
    for (i=1; i<=NUM_TASKS; i++)
    {
        if (i > THREAD_POOL_SIZE)
        {
            WaitForSingleObject(hThrds[slot], INFINITE);
            MTVERIFY( GetExitCodeThread(hThrds[slot], &exitCode) );
            printf("Slot %d terminated\n", exitCode );
            MTVERIFY( CloseHandle(hThrds[slot]) );
        }
        MTVERIFY( hThrds[slot] = CreateThread(NULL,
            0,
            ThreadFunc,
            (LPVOID)slot,
            0,
            &threadId ) );
        printf("Launched thread #%d (slot %d)\n", i, slot);
        if (++slot > MAX_THREAD_INDEX)
            slot = 0;
    }
    for (slot=0; slot<THREAD_POOL_SIZE; slot++)
    {
        WaitForSingleObject(hThrds[slot], INFINITE);
        MTVERIFY( CloseHandle(hThrds[slot]) );
    }
    printf("All slots terminated\n");

    return EXIT_SUCCESS;
}

/*
 * This function just calls Sleep for
 * a random amount of time, thereby
 * simulating some tasks that takes time.
 *
 * The param "n" is the index into
 * the handle array, kept for informational
 * purposes.
 */
DWORD WINAPI ThreadFunc(LPVOID n)
{
    srand( GetTickCount() );

    Sleep((rand()%8)*500+500);
    printf("Slot %d idle\n", n);
    return ((DWORD)n);
}

od

 

00401000  /$  81EC 1C010000 sub     esp, 11C
00401006  |.  53            push    ebx
00401007  |.  55            push    ebp
00401008  |.  8B2D 20204000 mov     ebp, dword ptr [<&KERNEL32.WaitF>;  kernel32.WaitForSingleObject
0040100E  |.  56            push    esi
0040100F  |.  57            push    edi
00401010  |.  33F6          xor     esi, esi
00401012  |.  BB 01000000   mov     ebx, 1
00401017  |>  83FB 03       /cmp     ebx, 3
0040101A  |.  7E 3F         |jle     short 0040105B
0040101C  |.  8B7CB4 20     |mov     edi, dword ptr [esp+esi*4+20]
00401020  |.  6A FF         |push    -1
00401022  |.  57            |push    edi
00401023  |.  FFD5          |call    ebp
00401025  |.  8D4424 18     |lea     eax, dword ptr [esp+18]
00401029  |.  50            |push    eax                             ; /pExitCode
0040102A  |.  57            |push    edi                             ; |hThread
0040102B  |.  FF15 1C204000 |call    dword ptr [<&KERNEL32.GetExitCo>; \GetExitCodeThread
00401031  |.  85C0          |test    eax, eax
00401033  |.  0F84 A7000000 |je      004010E0
00401039  |.  8B4C24 18     |mov     ecx, dword ptr [esp+18]
0040103D  |.  51            |push    ecx                             ; /<%d>
0040103E  |.  68 30314000   |push    00403130                        ; |format = "Slot %d terminated",LF,""
00401043  |.  FF15 34204000 |call    dword ptr [<&MSVCRTD.printf>]   ; \printf
00401049  |.  83C4 08       |add     esp, 8
0040104C  |.  57            |push    edi                             ; /hObject
0040104D  |.  FF15 18204000 |call    dword ptr [<&KERNEL32.CloseHand>; \CloseHandle
00401053  |.  85C0          |test    eax, eax
00401055  |.  0F84 05010000 |je      00401160
0040105B  |>  8D5424 1C     |lea     edx, dword ptr [esp+1C]
0040105F  |.  52            |push    edx                             ; /pThreadId
00401060  |.  6A 00         |push    0                               ; |CreationFlags = 0
00401062  |.  56            |push    esi                             ; |pThreadParm
00401063  |.  68 E0124000   |push    004012E0                        ; |ThreadFunction = TaskQueS.004012E0
00401068  |.  6A 00         |push    0                               ; |StackSize = 0
0040106A  |.  6A 00         |push    0                               ; |pSecurity = NULL
0040106C  |.  FF15 14204000 |call    dword ptr [<&KERNEL32.CreateThr>; \CreateThread
00401072  |.  85C0          |test    eax, eax
00401074  |.  8944B4 20     |mov     dword ptr [esp+esi*4+20], eax
00401078  |.  0F84 62010000 |je      004011E0
0040107E  |.  56            |push    esi                             ; /<%d>
0040107F  |.  53            |push    ebx                             ; |<%d>
00401080  |.  68 10314000   |push    00403110                        ; |format = "Launched thread #%d (slot %d)",LF,""
00401085  |.  FF15 34204000 |call    dword ptr [<&MSVCRTD.printf>]   ; \printf
0040108B  |.  83C4 0C       |add     esp, 0C
0040108E  |.  46            |inc     esi
0040108F  |.  83FE 02       |cmp     esi, 2
00401092  |.  7E 02         |jle     short 00401096
00401094  |.  33F6          |xor     esi, esi
00401096  |>  43            |inc     ebx
00401097  |.  83FB 06       |cmp     ebx, 6
0040109A  |.^ 0F8E 77FFFFFF \jle     00401017
004010A0  |.  33DB          xor     ebx, ebx
004010A2  |.  8D7C24 20     lea     edi, dword ptr [esp+20]
004010A6  |>  8B37          /mov     esi, dword ptr [edi]
004010A8  |.  6A FF         |push    -1
004010AA  |.  56            |push    esi
004010AB  |.  FFD5          |call    ebp
004010AD  |.  56            |push    esi                             ; /hObject
004010AE  |.  FF15 18204000 |call    dword ptr [<&KERNEL32.CloseHand>; \CloseHandle
004010B4  |.  85C0          |test    eax, eax
004010B6  |.  0F84 A4010000 |je      00401260
004010BC  |.  43            |inc     ebx
004010BD  |.  83C7 04       |add     edi, 4
004010C0  |.  83FB 03       |cmp     ebx, 3
004010C3  |.^ 7C E1         \jl      short 004010A6
004010C5  |.  68 F8304000   push    004030F8                         ; /format = "All slots terminated",LF,""
004010CA  |.  FF15 34204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf
004010D0  |.  83C4 04       add     esp, 4
004010D3  |.  33C0          xor     eax, eax
004010D5  |.  5F            pop     edi
004010D6  |.  5E            pop     esi
004010D7  |.  5D            pop     ebp
004010D8  |.  5B            pop     ebx
004010D9  |.  81C4 1C010000 add     esp, 11C
004010DF  |.  C3            retn

 

 

thread

 

004012E0  |.  56            push    esi
004012E1  |.  FF15 24204000 call    dword ptr [<&KERNEL32.GetTickCou>; [GetTickCount
004012E7  |.  50            push    eax                              ; /seed
004012E8  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.srand>]     ; \srand
004012EE  |.  83C4 04       add     esp, 4
004012F1  |.  FF15 38204000 call    dword ptr [<&MSVCRTD.rand>]      ; [rand
004012F7  |.  25 07000080   and     eax, 80000007
004012FC  |.  79 05         jns     short 00401303
004012FE  |.  48            dec     eax
004012FF  |.  83C8 F8       or      eax, FFFFFFF8
00401302  |.  40            inc     eax
00401303  |>  40            inc     eax
00401304  |.  8D0480        lea     eax, dword ptr [eax+eax*4]
00401307  |.  8D0480        lea     eax, dword ptr [eax+eax*4]
0040130A  |.  8D0480        lea     eax, dword ptr [eax+eax*4]
0040130D  |.  C1E0 02       shl     eax, 2
00401310  |.  50            push    eax                              ; /Timeout
00401311  |.  FF15 00204000 call    dword ptr [<&KERNEL32.Sleep>]    ; \Sleep
00401317  |.  8B7424 08     mov     esi, dword ptr [esp+8]
0040131B  |.  56            push    esi                              ; /<%d>
0040131C  |.  68 44314000   push    00403144                         ; |format = "Slot %d idle",LF,""
00401321  |.  FF15 34204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf
00401327  |.  83C4 08       add     esp, 8
0040132A  |.  8BC6          mov     eax, esi
0040132C  |.  5E            pop     esi
0040132D  \.  C2 0400       retn    4

 

ida

 

posted @ 2010-07-08 13:47  南守拥  阅读(180)  评论(0编辑  收藏  举报