/*
* Numbers2.cpp
*
* Sample code for "Multithreading Applications in Win32"
* This is from Chapter 10, Listing 10-2
*
* Demonstrate thread startup in MFC
* using AfxBeginThread, but prevent
* CWinThread from auto-deletion so that
* we can wait on the thread.
*
* Compile with the IDE or: nmake -f numbers2.mak
*/
#include <afxwin.h>
CWinApp TheApp;
UINT ThreadFunc(LPVOID);
int main()
{
CWinThread* pThreads[5];
for (int i=0; i<5; i++)
{
pThreads[i] = AfxBeginThread(
ThreadFunc,
(LPVOID)i,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED
);
ASSERT(pThreads[i]);
pThreads[i]->m_bAutoDelete = FALSE;
pThreads[i]->ResumeThread();
printf("Thread launched %d\n", i);
}
for (i=0; i<5; i++)
{
WaitForSingleObject(pThreads[i]->m_hThread, INFINITE);
delete pThreads[i];
}
return 0;
}
UINT ThreadFunc(LPVOID n)
{
for (int i=0;i<10;i++)
printf("%d%d%d%d%d%d%d%d\n",n,n,n,n,n,n,n,n);
return 0;
}
od
main thread
00401040 /$ 83EC 14 sub esp, 14
00401043 |. 53 push ebx
00401044 |. 8B1D 54204000 mov ebx, dword ptr [<&MSVCRT.printf>>; msvcrt.printf
0040104A |. 55 push ebp
0040104B |. 8B2D 04204000 mov ebp, dword ptr [<&KERNEL32.Resum>; kernel32.ResumeThread
00401051 |. 56 push esi
00401052 |. 57 push edi
00401053 |. 33F6 xor esi, esi
00401055 |. 8D7C24 10 lea edi, dword ptr [esp+10]
00401059 |> 6A 00 /push 0
0040105B |. 6A 04 |push 4
0040105D |. 6A 00 |push 0
0040105F |. 6A 00 |push 0
00401061 |. 56 |push esi
00401062 |. 68 D0104000 |push 004010D0
00401067 |. E8 A0000000 |call <jmp.&MFC42.#1105_AfxBeginThrea>
0040106C |. 8907 |mov dword ptr [edi], eax ; hanler->pThreads[i]
0040106E |. C740 28 00000>|mov dword ptr [eax+28], 0
00401075 |. 8B40 2C |mov eax, dword ptr [eax+2C]
00401078 |. 50 |push eax
00401079 |. FFD5 |call ebp ; ResumeThread
0040107B |. 56 |push esi
0040107C |. 68 20304000 |push 00403020 ; ASCII "Thread launched %d",LF
00401081 |. FFD3 |call ebx ; printf
00401083 |. 83C4 08 |add esp, 8
00401086 |. 46 |inc esi ; i++
00401087 |. 83C7 04 |add edi, 4 ; pThreads++
0040108A |. 83FE 05 |cmp esi, 5 ; i<5
0040108D |.^ 7C CA \jl short 00401059
0040108F |. 8B1D 00204000 mov ebx, dword ptr [<&KERNEL32.WaitF>; kernel32.WaitForSingleObject
00401095 |. 8D7C24 10 lea edi, dword ptr [esp+10]
00401099 |. BD 05000000 mov ebp, 5
0040109E |> 8B37 /mov esi, dword ptr [edi]
004010A0 |. 6A FF |push -1
004010A2 |. 8B4E 2C |mov ecx, dword ptr [esi+2C]
004010A5 |. 51 |push ecx
004010A6 |. FFD3 |call ebx
004010A8 |. 85F6 |test esi, esi
004010AA |. 74 09 |je short 004010B5
004010AC |. 8B16 |mov edx, dword ptr [esi]
004010AE |. 6A 01 |push 1
004010B0 |. 8BCE |mov ecx, esi
004010B2 |. FF52 04 |call dword ptr [edx+4]
004010B5 |> 83C7 04 |add edi, 4
004010B8 |. 4D |dec ebp
004010B9 |.^ 75 E3 \jnz short 0040109E
004010BB |. 5F pop edi
004010BC |. 5E pop esi
004010BD |. 5D pop ebp
004010BE |. 33C0 xor eax, eax
004010C0 |. 5B pop ebx
004010C1 |. 83C4 14 add esp, 14
004010C4 \. C3 retn
thread
004010D0 . 53 push ebx
004010D1 . 56 push esi
004010D2 . 8B7424 0C mov esi, dword ptr [esp+C] ; n
004010D6 . 57 push edi
004010D7 . 8B3D 54204000 mov edi, dword ptr [<&MSVCRT.printf>>; msvcrt.printf
004010DD . BB 0A000000 mov ebx, 0A ; i=10
004010E2 > 56 push esi
004010E3 . 56 push esi
004010E4 . 56 push esi
004010E5 . 56 push esi
004010E6 . 56 push esi
004010E7 . 56 push esi
004010E8 . 56 push esi
004010E9 . 56 push esi
004010EA . 68 34304000 push 00403034 ; ASCII "%d%d%d%d%d%d%d%d",LF
004010EF . FFD7 call edi ; printf
004010F1 . 83C4 24 add esp, 24
004010F4 . 4B dec ebx ; i--
004010F5 .^ 75 EB jnz short 004010E2
004010F7 . 5F pop edi
004010F8 . 5E pop esi
004010F9 . 33C0 xor eax, eax
004010FB . 5B pop ebx
004010FC . C3 retn
ida
.text:00401040
.text:00401040 ; =============== S U B R O U T I N E =======================================
.text:00401040
.text:00401040
.text:00401040 ; int __cdecl main(int argc, const char **argv, const char *envp)
.text:00401040 _main proc near ; CODE XREF: start+DEp
.text:00401040
.text:00401040 pThreads = word ptr -14h
.text:00401040 var_1 = byte ptr -1
.text:00401040 argc = dword ptr 4
.text:00401040 argv = dword ptr 8
.text:00401040 envp = dword ptr 0Ch
.text:00401040
.text:00401040 sub esp, 14h
.text:00401043 push ebx
.text:00401044 mov ebx, ds:printf
.text:0040104A push ebp
.text:0040104B mov ebp, ds:ResumeThread
.text:00401051 push esi
.text:00401052 push edi
.text:00401053 xor esi, esi
.text:00401055 lea edi, [esp+24h+pThreads]
.text:00401059
.text:00401059 loc_401059: ; CODE XREF: _main+4Dj
.text:00401059 push 0
.text:0040105B push 4
.text:0040105D push 0
.text:0040105F push 0
.text:00401061 push esi
.text:00401062 push offset ThreadFunc
.text:00401067 call ?AfxBeginThread@@YGPAVCWinThread@@P6AIPAX@Z0HIKPAU_SECURITY_ATTRIBUTES@@@Z ; AfxBeginThread(uint (*)(void *),void *,int,uint,ulong,_SECURITY_ATTRIBUTES *)
.text:0040106C mov [edi], eax ; pTheads[i]=handler
.text:0040106E mov dword ptr [eax+28h], 0
.text:00401075 mov eax, [eax+2Ch]
.text:00401078 push eax ; hThread
.text:00401079 call ebp ; ResumeThread
.text:0040107B push esi
.text:0040107C push offset Format ; "Thread launched %d\n"
.text:00401081 call ebx ; printf
.text:00401083 add esp, 8
.text:00401086 inc esi
.text:00401087 add edi, 4 ; pThreads++
.text:0040108A cmp esi, 5 ; i<5
.text:0040108D jl short loc_401059
.text:0040108F mov ebx, ds:WaitForSingleObject
.text:00401095 lea edi, [esp+24h+pThreads]
.text:00401099 mov ebp, 5
.text:0040109E
.text:0040109E loc_40109E: ; CODE XREF: _main+79j
.text:0040109E mov esi, [edi]
.text:004010A0 push 0FFFFFFFFh ; dwMilliseconds
.text:004010A2 mov ecx, [esi+2Ch]
.text:004010A5 push ecx ; hHandle
.text:004010A6 call ebx ; WaitForSingleObject
.text:004010A8 test esi, esi
.text:004010AA jz short loc_4010B5
.text:004010AC mov edx, [esi]
.text:004010AE push 1
.text:004010B0 mov ecx, esi
.text:004010B2 call dword ptr [edx+4];Delete pThread[i]
.text:004010B5
.text:004010B5 loc_4010B5: ; CODE XREF: _main+6Aj
.text:004010B5 add edi, 4
.text:004010B8 dec ebp
.text:004010B9 jnz short loc_40109E
.text:004010BB pop edi
.text:004010BC pop esi
.text:004010BD pop ebp
.text:004010BE xor eax, eax
.text:004010C0 pop ebx
.text:004010C1 add esp, 14h
.text:004010C4 retn
.text:004010C4 _main endp
.text:004010C4
thread
.text:004010D0
.text:004010D0 ; =============== S U B R O U T I N E =======================================
.text:004010D0
.text:004010D0
.text:004010D0 ThreadFunc proc near ; DATA XREF: _main+22o
.text:004010D0
.text:004010D0 var_n = dword ptr 4
.text:004010D0
.text:004010D0 push ebx
.text:004010D1 push esi
.text:004010D2 mov esi, [esp+8+var_n]
.text:004010D6 push edi
.text:004010D7 mov edi, ds:printf
.text:004010DD mov ebx, 0Ah ; i=10
.text:004010E2
.text:004010E2 loc_4010E2: ; CODE XREF: ThreadFunc+25j
.text:004010E2 push esi
.text:004010E3 push esi
.text:004010E4 push esi
.text:004010E5 push esi
.text:004010E6 push esi
.text:004010E7 push esi
.text:004010E8 push esi
.text:004010E9 push esi
.text:004010EA push offset aDDDDDDDD ; "%d%d%d%d%d%d%d%d\n"
.text:004010EF call edi ; printf
.text:004010F1 add esp, 24h
.text:004010F4 dec ebx ; i--
.text:004010F5 jnz short loc_4010E2
.text:004010F7 pop edi
.text:004010F8 pop esi
.text:004010F9 xor eax, eax
.text:004010FB pop ebx
.text:004010FC retn
.text:004010FC ThreadFunc endp
.text:004010FC
.text:004010FC ; ---------------------------------------------------------------------------
.text:004010FD align 10h