/* * ExitCode.c * * Sample code for "Multithreading Applications in Win32" * This is from Chapter 2, Listing 2-2 * * Start two threads and try to exit * when the user presses a key. */
#define WIN32_LEAN_AND_MEAN#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <conio.h>
DWORD WINAPI ThreadFunc(LPVOID);
int main(){ HANDLE hThrd1; HANDLE hThrd2; DWORD exitCode1 = 0; DWORD exitCode2 = 0; DWORD threadId; hThrd1 = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &threadId ); if (hThrd1) printf("Thread 1 launched\n");
hThrd2 = CreateThread(NULL, 0, ThreadFunc, (LPVOID)2, 0, &threadId ); if (hThrd2) printf("Thread 2 launched\n");
// Keep waiting until both calls to // GetExitCodeThread succeed AND // neither of them returns STILL_ACTIVE. // This method is not optimal - we'll // see the correct way in Chapter 3. for (;;) { printf("Press any key to exit..\n"); getch();
GetExitCodeThread(hThrd1, &exitCode1); GetExitCodeThread(hThrd2, &exitCode2); if ( exitCode1 == STILL_ACTIVE ) puts("Thread 1 is still running!"); if ( exitCode2 == STILL_ACTIVE ) puts("Thread 2 is still running!"); if ( exitCode1 != STILL_ACTIVE && exitCode2 != STILL_ACTIVE ) break; }
CloseHandle(hThrd1); CloseHandle(hThrd2);
printf("Thread 1 returned %d\n", exitCode1); printf("Thread 2 returned %d\n", exitCode2);
return EXIT_SUCCESS;}
/* * Take the startup value, do some simple math on it, * and return the calculated value. */DWORD WINAPI ThreadFunc(LPVOID n){ Sleep((DWORD)n*1000*2); return (DWORD)n * 10;}od
00401000 /$ 83EC 0C sub esp, 0C00401003 |. 53 push ebx00401004 |. 55 push ebp00401005 |. 56 push esi00401006 |. 8B35 04204000 mov esi, dword ptr [<&KERNEL32.Creat>; kernel32.CreateThread0040100C |. 57 push edi0040100D |. 8D4424 18 lea eax, dword ptr [esp+18]00401011 |. 33FF xor edi, edi00401013 |. 50 push eax ; /pThreadId00401014 |. 57 push edi ; |CreationFlags => 000401015 |. 6A 01 push 1 ; |pThreadParm = 0000000100401017 |. 68 00114000 push 00401100 ; |ThreadFunction = ExitCode.004011000040101C |. 57 push edi ; |StackSize => 00040101D |. 57 push edi ; |pSecurity => NULL0040101E |. 897C24 28 mov dword ptr [esp+28], edi ; |00401022 |. 897C24 2C mov dword ptr [esp+2C], edi ; |00401026 |. FFD6 call esi ; \CreateThread00401028 |. 8B2D 18204000 mov ebp, dword ptr [<&MSVCRTD.printf>; MSVCRTD.printf0040102E |. 8BD8 mov ebx, eax00401030 |. 3BDF cmp ebx, edi ; 创建成功00401032 |. 74 0A je short 0040103E00401034 |. 68 A8304000 push 004030A8 ; /format = "Thread 1 launched",LF,""00401039 |. FFD5 call ebp ; \printf0040103B |. 83C4 04 add esp, 40040103E |> 8D4C24 18 lea ecx, dword ptr [esp+18]00401042 |. 51 push ecx00401043 |. 57 push edi00401044 |. 6A 02 push 200401046 |. 68 00114000 push 004011000040104B |. 57 push edi0040104C |. 57 push edi0040104D |. FFD6 call esi ; CreateThread0040104F |. 8BF8 mov edi, eax00401051 |. 85FF test edi, edi00401053 |. 74 0A je short 0040105F00401055 |. 68 94304000 push 00403094 ; ASCII "Thread 2 launched",LF0040105A |. FFD5 call ebp0040105C |. 83C4 04 add esp, 40040105F |> 8B35 00204000 mov esi, dword ptr [<&KERNEL32.GetEx>; kernel32.GetExitCodeThread00401065 |> 68 78304000 /push 00403078 ; ASCII "Press any key to exit..",LF0040106A |. FFD5 |call ebp ; Printf0040106C |. 83C4 04 |add esp, 40040106F |. FF15 50204000 |call dword ptr [<&MSVCRTD._getch>] ; [_getch00401075 |. 8D5424 10 |lea edx, dword ptr [esp+10] ; hThrd100401079 |. 52 |push edx0040107A |. 53 |push ebx0040107B |. FFD6 |call esi ; kernel32.GetExitCodeThread0040107D |. 8D4424 14 |lea eax, dword ptr [esp+14] ; hThrd200401081 |. 50 |push eax00401082 |. 57 |push edi00401083 |. FFD6 |call esi ; kernel32.GetExitCodeThread00401085 |. 8B4C24 10 |mov ecx, dword ptr [esp+10]00401089 |. B8 03010000 |mov eax, 103 ; STILL_ACTIVE0040108E |. 3BC8 |cmp ecx, eax00401090 |. 75 13 |jnz short 004010A500401092 |. 68 5C304000 |push 0040305C ; /s = "Thread 1 is still running!"00401097 |. FF15 14204000 |call dword ptr [<&MSVCRTD.puts>] ; \puts0040109D |. 83C4 04 |add esp, 4004010A0 |. B8 03010000 |mov eax, 103 ; STILL_ACTIVE004010A5 |> 394424 14 |cmp dword ptr [esp+14], eax004010A9 |. 75 13 |jnz short 004010BE004010AB |. 68 40304000 |push 00403040 ; /s = "Thread 2 is still running!"004010B0 |. FF15 14204000 |call dword ptr [<&MSVCRTD.puts>] ; \puts004010B6 |. 83C4 04 |add esp, 4004010B9 |. B8 03010000 |mov eax, 103004010BE |> 394424 10 |cmp dword ptr [esp+10], eax004010C2 |.^ 74 A1 |je short 00401065004010C4 |. 394424 14 |cmp dword ptr [esp+14], eax004010C8 |.^ 74 9B \je short 00401065004010CA |. 8B35 0C204000 mov esi, dword ptr [<&KERNEL32.Close>; kernel32.CloseHandle004010D0 |. 53 push ebx ; /hObject004010D1 |. FFD6 call esi ; \CloseHandle004010D3 |. 57 push edi ; /hObject004010D4 |. FFD6 call esi ; \CloseHandle004010D6 |. 8B4C24 10 mov ecx, dword ptr [esp+10]004010DA |. 51 push ecx004010DB |. 68 28304000 push 00403028 ; ASCII "Thread 1 returned %d",LF004010E0 |. FFD5 call ebp004010E2 |. 8B5424 1C mov edx, dword ptr [esp+1C]004010E6 |. 52 push edx004010E7 |. 68 10304000 push 00403010 ; ASCII "Thread 2 returned %d",LF004010EC |. FFD5 call ebp004010EE |. 83C4 10 add esp, 10004010F1 |. 33C0 xor eax, eax004010F3 |. 5F pop edi004010F4 |. 5E pop esi004010F5 |. 5D pop ebp004010F6 |. 5B pop ebx004010F7 |. 83C4 0C add esp, 0C004010FA \. C3 retn
thread
00401100 . 56 push esi00401101 . 8B7424 08 mov esi, dword ptr [esp+8]00401105 . 8D04B6 lea eax, dword ptr [esi+esi*4] ; eax=esi*500401108 . 8D0480 lea eax, dword ptr [eax+eax*4] ; eax=eax*50040110B . 8D0480 lea eax, dword ptr [eax+eax*4] ; eax=eax*50040110E . C1E0 04 shl eax, 4 ; 左移四位00401111 . 50 push eax ; /Timeout00401112 . FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep00401118 . 8D04B6 lea eax, dword ptr [esi+esi*4] ; eax=esi*50040111B . 5E pop esi0040111C . D1E0 shl eax, 1 ; eax左移一位0040111E . C2 0400 retn 4
ida
.text:00401000.text:00401000 ; =============== S U B R O U T I N E =======================================.text:00401000.text:00401000.text:00401000 ; int __cdecl main(int argc, const char **argv, const char *envp).text:00401000 _main proc near ; CODE XREF: start+FAp.text:00401000.text:00401000 ExitCode = dword ptr -0Ch.text:00401000 ExitCode1 = dword ptr -8.text:00401000 ThreadId = dword ptr -4.text:00401000 argc = dword ptr 4.text:00401000 argv = dword ptr 8.text:00401000 envp = dword ptr 0Ch.text:00401000.text:00401000 sub esp, 0Ch.text:00401003 push ebx.text:00401004 push ebp.text:00401005 push esi.text:00401006 mov esi, ds:CreateThread.text:0040100C push edi.text:0040100D lea eax, [esp+1Ch+ThreadId].text:00401011 xor edi, edi ; edi=0.text:00401013 push eax ; lpThreadId.text:00401014 push edi ; dwCreationFlags.text:00401015 push 1 ; lpParameter.text:00401017 push offset StartAddress ; lpStartAddress.text:0040101C push edi ; dwStackSize.text:0040101D push edi ; lpThreadAttributes.text:0040101E mov [esp+34h+ExitCode], edi.text:00401022 mov [esp+34h+ExitCode1], edi.text:00401026 call esi ; CreateThread.text:00401028 mov ebp, ds:printf.text:0040102E mov ebx, eax.text:00401030 cmp ebx, edi.text:00401032 jz short loc_40103E.text:00401034 push offset Format ; "Thread 1 launched\n".text:00401039 call ebp ; printf.text:0040103B add esp, 4.text:0040103E.text:0040103E loc_40103E: ; CODE XREF: _main+32j.text:0040103E lea ecx, [esp+1Ch+ThreadId].text:00401042 push ecx ; lpThreadId.text:00401043 push edi ; dwCreationFlags.text:00401044 push 2 ; lpParameter.text:00401046 push offset StartAddress ; lpStartAddress.text:0040104B push edi ; dwStackSize.text:0040104C push edi ; lpThreadAttributes.text:0040104D call esi ; CreateThread.text:0040104F mov edi, eax.text:00401051 test edi, edi.text:00401053 jz short loc_40105F.text:00401055 push offset aThread2Launche ; "Thread 2 launched\n".text:0040105A call ebp ; printf.text:0040105C add esp, 4.text:0040105F.text:0040105F loc_40105F: ; CODE XREF: _main+53j.text:0040105F mov esi, ds:GetExitCodeThread.text:00401065.text:00401065 loc_401065: ; CODE XREF: _main+C2j.text:00401065 ; _main+C8j.text:00401065 push offset aPressAnyKeyToE ; "Press any key to exit..\n".text:0040106A call ebp ; printf.text:0040106C add esp, 4.text:0040106F call ds:_getch.text:00401075 lea edx, [esp+1Ch+ExitCode].text:00401079 push edx ; lpExitCode.text:0040107A push ebx ; hThread.text:0040107B call esi ; GetExitCodeThread.text:0040107D lea eax, [esp+1Ch+ExitCode1].text:00401081 push eax ; lpExitCode.text:00401082 push edi ; hThread.text:00401083 call esi ; GetExitCodeThread.text:00401085 mov ecx, [esp+1Ch+ExitCode].text:00401089 mov eax, STILL_ACTIVE.text:0040108E cmp ecx, eax.text:00401090 jnz short loc_4010A5.text:00401092 push offset Str ; "Thread 1 is still running!".text:00401097 call ds:puts.text:0040109D add esp, 4.text:004010A0 mov eax, STILL_ACTIVE.text:004010A5.text:004010A5 loc_4010A5: ; CODE XREF: _main+90j.text:004010A5 cmp [esp+1Ch+ExitCode1], eax.text:004010A9 jnz short loc_4010BE.text:004010AB push offset aThread2IsStill ; "Thread 2 is still running!".text:004010B0 call ds:puts.text:004010B6 add esp, 4.text:004010B9 mov eax, STILL_ACTIVE.text:004010BE.text:004010BE loc_4010BE: ; CODE XREF: _main+A9j.text:004010BE cmp [esp+1Ch+ExitCode], eax.text:004010C2 jz short loc_401065.text:004010C4 cmp [esp+1Ch+ExitCode1], eax.text:004010C8 jz short loc_401065.text:004010CA mov esi, ds:CloseHandle.text:004010D0 push ebx ; hObject.text:004010D1 call esi ; CloseHandle.text:004010D3 push edi ; hObject.text:004010D4 call esi ; CloseHandle.text:004010D6 mov ecx, [esp+1Ch+ExitCode].text:004010DA push ecx.text:004010DB push offset aThread1Returne ; "Thread 1 returned %d\n".text:004010E0 call ebp ; printf.text:004010E2 mov edx, [esp+24h+ExitCode1].text:004010E6 push edx.text:004010E7 push offset aThread2Returne ; "Thread 2 returned %d\n".text:004010EC call ebp ; printf.text:004010EE add esp, 10h.text:004010F1 xor eax, eax.text:004010F3 pop edi.text:004010F4 pop esi.text:004010F5 pop ebp.text:004010F6 pop ebx.text:004010F7 add esp, 0Ch.text:004010FA retn.text:004010FA _main endp.text:004010FA.text:004010FA ; ---------------------------------------------------------------------------.text:004010FB align 10h.text:00401100.text:00401100 ; =============== S U B R O U T I N E =======================================.text:00401100.text:00401100
thread
.text:00401100.text:00401100 ; =============== S U B R O U T I N E =======================================.text:00401100.text:00401100.text:00401100 ; DWORD __stdcall StartAddress(LPVOID).text:00401100 StartAddress proc near ; DATA XREF: _main+17o.text:00401100 ; _main+46o.text:00401100.text:00401100 argn = dword ptr 4.text:00401100.text:00401100 push esi.text:00401101 mov esi, [esp+4+argn].text:00401105 lea eax, [esi+esi*4].text:00401108 lea eax, [eax+eax*4].text:0040110B lea eax, [eax+eax*4].text:0040110E shl eax, 4.text:00401111 push eax ; dwMilliseconds.text:00401112 call ds:Sleep.text:00401118 lea eax, [esi+esi*4].text:0040111B pop esi.text:0040111C shl eax, 1.text:0040111E retn 4.text:0040111E StartAddress endp.text:0040111E.text:0040111E ; ---------------------------------------------------------------------------
转载于:https://www.cnblogs.com/nanshouyong326/archive/2010/07/07/1772689.html
