Threads

Now, it is time to consider threads in more detail. First, try to solve the problem from the previous chapter (see Listing 14.2) using the thread.

A thread can be created using the CreateThread function. This function accepts the following parameters:

  • First parameterThis is a pointer to the structure of the access attributes. It has meaning only for the Windows NT family. As a rule, this parameter is set to NULL .

  • Second parameterThis is the size of the thread's stack. If this parameter is set to zero, then the default stack size is taken, which is the size of the stack of the parent thread.

  • Third parameterThis is a pointer to the thread function. Thread execution starts from the call to this function.

  • Fourth parameterThis is the parameter for the thread function.

  • Fifth parameterThis flag defines the thread state. If this flag is zero, then thread execution starts immediately. If the flag value is CREATE_SUSPENDED (4H) , the thread is in the waiting state and starts after the ResumeThread function has been executed.

  • Sixth parameterThis is the pointer to the variable, into which the thread handle will be placed.

As already mentioned, thread execution starts from the thread function. Termination of this function naturally terminates the thread (exiting the function using RET ). The thread can also terminate execution by executing the ExitThread function, specifying the exit code. Finally, the generating thread might terminate the operation of the generated thread using the TerminateThread function. In Listing 15.2, the generated process cannot terminate its operation and terminates with the application in response to TerminateThread . It is necessary to point out that such termination is abnormal and is not recommended for everyday use. This is because when using this type of termination, the system doesn't carry out any actions related to releasing allocated resources (memory blocks, opened files, etc.). Therefore, it is recommended that you build your applications so that the thread would terminate by exiting the thread procedure. Thus, the example in Listing 15.2 demonstrates some of don'ts.

In an ideal situation, the window function takes responsibility for reaction only to events that take place in relation to its elements; all other jobs (e.g., complex computations and file processing) are the responsibility of threads. By the way, a thread can generate other threads, so an entire branched tree may appear as a result.

As I have mentioned already, the program in Listing 15.2 uses a thread to compute the current data and time and display them in the edit window. Note that if such processing is implemented in the window function, you would immediately notice the difference because the window would cease to react to nearly all of your actions.

Listing 15.2: Creating a thread
image from book
 // The TIMER2.RC file // Constants definitions #define WS_SYSMENU                Ox00080000L // The window elements must be initially visible #define WS_VISIBLE                0xl0000000L // Border around the element #define WS_BORDER                 0x00800000L // Elements can be activated using the <Tab> key #define WS_TABSTOP                0x00010000L // Text in the edit field is left-aligned #define ES_LEFT                   0x0000L // Style of all window elements #define WS_CHILD                  0x40000000L // Keyboard input is disabled #define ES_READONLY               0x0800L // Button style #define BS_PUSHBUTTON             0x00000000L // Center the button label #define BS_CENTER                 0x00000300L #define DS_3DLOOK                 0x0004L // Dialog box definition DIAL1 DIALOG 0, 0, 240, 100 STYLE WS_SYSMENU  DS_3DLOOK CAPTION "Example of the thread usage" FONT 8, "Arial" { // Edit field, identifier 1  CONTROL "", 1, "edit", ES_LEFT  WS_CHILD   WS_VISIBLE  WS_BORDER   WS_TABSTOP  ES_READONLY, 100, 5, 130, 12 // Button, identifier 2  CONTROL "Exit", 2, "button", BS_PUSHBUTTON   BS CENTER  WS_CHILD  WS_VISIBLE  WS_TABSTOP,  180, 76, 50, 14 } ; The TIMER2.INC file ; Constants ; The message arrives when the window is closed WM_CLOSE       equ 10h ; The message arrives when the window is created WM_INITDIALOG  equ 110h ; The message arrives when something happens to ; the window elements WM_COMMAND     equ 111h ; This message sends the text to the window element WM_SETTEXT     equ 0Ch ; Prototypes of external procedures IFDEF MASM ; For MASM         EXTERN     SendMessageA@16:NEAR         EXTERN     GetDlgItem@8:NEAR         EXTERN     Sleep@4:NEAR         EXTERN     TerminateThread@8:NEAR         EXTERN     CreateThread@24:NEAR         EXTERN     wsprintfA:NEAR         EXTERN     GetLocalTime@4:NEAR         EXTERN     ExitProcess@4:NEAR         EXTERN     GetModuleHandleA@ 4:NEAR         EXTERN     DialogBoxParamA@20:NEAR         EXTERN     EndDialog@8:NEAR ELSE ; For TASM         EXTERN     SendMessageA:NEAR         EXTERN     GetDlgItem:NEAR         EXTERN     Sleep:NEAR         EXTERN     TerminateThread:NEAR         EXTERN     CreateThread:NEAR         EXTERN     _wsprintfA:NEAR         EXTERN     GetLocalTime:NEAR         EXTERN     ExitProcess:NEAR         EXTERN     GetModuleHandleA:NEAR         EXTERN     DialogBoxParamA:NEAR         EXTERN     EndDialog:NEAR         SendMessageA@16 = SendMessageA         GetDlgItem@8 = GetDlgItem         Sleep@4 = Sleep         TerminateThread@8 = TerminateThread         CreateThread@24 = CreateThread         wsprintfA = _wsprintfA         GetLocalTime@4 = GetLocalTime         ExitProcess@4 = ExitProcess         GetModuleHandleA@4 = GetModuleHandleA         DialogBoxParamA@20 = DialogBoxParamA         EndDialog@8 = EndDialog ENDIF ; Structures ; Message structure MSGSTRUCT STRUC         MSHWND         DD ?         MSMESSAGE      DD ?         MSWPARAM       DD ?         MSLPARAM       DD ?         MSTIME         DD ?         MSPT           DD ? MSGSTRUCT ENDS ; Date-time data structure DAT STRUC         year    DW ?         month   DW ?         dayweek DW ?         day     DW ?         hour    DW ?         min     DW ?         sec     DW ?         msec    DW ? DAT ENDS ; The TIMER2.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include thread.inc ; INCLUDELIB directives for the linker to link libraries IFDEF MASM ; For the LINK.EXE linker       includelib c:\masm32\lib\user32.lib       includelib c:\masm32\lib\kernel32.lib       includelib c:\masm32\lib\gdi32.lib ELSE ; For the TLINK32.EXE linker       includelib c:\tasm32\lib\import32.lib ENDIF ;----------------------------------------------- ; Data segment _DATA SEGMENT         MSG    MSGSTRUCT <?>         HINST  DD 0 ; Application descriptor         PA     DB "DIAL1", 0         TIM    DB "Date %u/%u/%u  Time %u:%u:%u", 0         STRCOPY DB 50 DUP(?)         DATA   DAT <0>         HTHR   DD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor         PUSH  0         CALL  GetModuleHandleA@4         MOV   [HINST], EAX ; Create a dialog         PUSH  0         PUSH  OFFSET WNDPROC         PUSH  0         PUSH  OFFSET PA         PUSH  [HINST]         CALL  DialogBoxParamA@20         CMP   EAX, -1         JNE   KOL ; Error message KOL: ;---------------------------------         PUSH  0         CALL ExitProcess@4 ;--------------------------------- ; Window procedure ; Position of parameters in the stack ; [EBP+014H]  ; LPARAM ; [EBP+10H]   ; WAPARAM ; [EBP+0CH]   ; MES ; [EBP+8]     ; HWND WNDPROC     PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  EBX         PUSH  ESI         PUSH  EDI ;----------------         CMP  DWORD PTR [EBP+0CH], WM_CLOSE         JNE  L1 L3: ; The reaction to closing the window ; Kill the thread         PUSH 0         PUSH HTHR         CALL TerminateThread@8 ; Close the dialog         PUSH 0         PUSH DWORD PTR [EBP+08H]         CALL EndDialog@8         JMP  FINISH L1:         CMP  DWORD PTR [EBP+0CH], WM_INITDIALOG         JNE  L2 ; Startup initialization ; Get the descriptor of the edit field         PUSH 1         PUSH DWORD PTR [EBP+08H]         CALL GetDlgItem@8 ; Create a thread         PUSH OFFSET HTHR    ; Thread descriptor goes here         PUSH 0         PUSH EAX            ; Parameter         PUSH OFFSET GETTIME ; Procedure address         PUSH 0         PUSH 0         CALL CreateThread@24         JMP  FINISH L2:         CMP  DWORD PTR [EBP+0CH], WM_COMMAND         JNE  FINISH ; Exit button?         CMP  WORD PTR [EBP+10H], 2         JE   L3 FINISH:         POP  EDI         POP  ESI         POP  EBX         POP  EBP         MOV  EAX, 0         RET  16 WNDPROC   ENDP ; Thread function ; [EBP+8] Parameter = Edit field descriptor GETTIME PROC         PUSH EBP         MOV  EBP, ESP LO: ; 1-second delay         PUSH 1000         CALL Sleep@4 ; Get local time         PUSH OFFSET DATA         CALL GetLocalTime@4 ; Get the string for data and time output         MOVZX EAX, DATA.sec         PUSH  EAX         MOVZX EAX, DATA.min         PUSH  EAX         MOVZX EAX, DATA.hour         PUSH  EAX         MOVZX EAX, DATA.year         PUSH  EAX         MOVZX EAX, DATA. month         PUSH  EAX         MOVZX EAX, DATA.day         PUSH  EAX         PUSH  OFFSET TIM         PUSH  OFFSET STRCOPY         CALL  wsprintfA ; Send the string to the edit window         PUSH  OFFSET STRCOPY         PUSH  0         PUSH  WM_SETTEXT         PUSH  DWORD PTR [EBP+08H]         CALL  SendMessageA@16         JMP   LO ; Endless loop         POP   EBP         RET   4 GETTIME ENDP _TEXT ENDS END START 
image from book
 

To translate the THREAD.ASM program presented in Listing 15.2, issue the following commands using MASM32:

 ML /c /coff /DMASM thread.asm!     RC thread.rc     LINK /SUBSYSTEM:WINDOWS thread.obj thread.res 

Issue the following commands using TASM32:

 TASM32  /ml thread.asm     BRCC32 thread.rc     TLINK32 -aa thread.obj,,,,,thread.res 

I recommend that you pay attention to a useful function Sleep . This function is frequently used in threads because it frees some processor time.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net