⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut15.html

📁 win32汇编教程 希望各位多多支持
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Iczelion">
   <meta name="GENERATOR" content="Mozilla/4.51 [en] (Win95; I) [Netscape]">
   <title>Iczelion's Win32 Assembly Tutorial 15: Multithreading Programming</title>
</head>
<body text="#FFFFFF" bgcolor="#000080" link="#FFFF00" vlink="#8080FF" alink="#FF00FF">

<center>
<h1>
<font face="Arial,Helvetica"><font color="#FFFFCC"><font size=+2>Tutorial
15: Multithreading Programming</font></font></font></h1></center>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>We will
learn how to create a multithreading program in this tutorial. We also
study the communication methods between the threads.</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font size=-1><font color="#FFFFFF">Download
the example </font><font color="#000000"><a href="files/tut15.zip">here</a>.</font></font></font>
<h3>
<font face="Arial,Helvetica"><font color="#33FF33"><font size=+0>Theory:</font></font></font></h3>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>In previous
tutorial, you learn the a process consists of at least one thread: the
primary thread. A thread is a chain of execution. You can also create additional
threads in your program. You can view multithreading as multitasking within
one program. In term of implementation, a thread is a function that runs
concurrently with the main program. You can run several instances of the
same function or you can run several functions simultaneously depending
on your requirement. Multithreading is specific to Win32, no Win16 counterpart
exists.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Threads
run in the same process so they can access any resources in the process
such as global variables, handles etc. However, each thread has its own
stack so local variables in each thread are private. Each thread also owns
its private register set so when Windows switches to other threads, the
thread can "remember" its last status and can "resume" the task when it
gains control again. This is handled internally by Windows.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>We
can divide threads into two caterories:</font></font></font>
<ol>
<li>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>User interface
thread: This type of thread creates its own window so it receives windows
messages. It can respond to the user via its own window hence the name.
This type of thread is subject to Win16 Mutex rule which allows only one
user interface thread in 16-bit user and gdi kernel. While a user interface
thread is executing code in 16-bit user and gdi kernel, other UI threads
cannot use the service of the 16-bit user and gdi kernel. Note that this
Win16 Mutex is specific to Windows 95 since underneath, Windows 95 API
functions thunk down to 16-bit code. Windows NT has no Win16 Mutex so the
user interface threads under NT work more smoothly than under Windows 95.</font></font></font></li>

<li>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Worker
thread: This type of thread does not create a window so it cannot receive
any windows message. It exists primarily to do the assigned job in the
background hence the name worker thread.</font></font></font></li>
</ol>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>I advise
the following strategy when using multithreading capability of Win32: Let
the primary thread do user interface stuff and the other threads do the
hard work in the background. In this way, the primary thread is like a
Governor, other threads are like the Governor's staff. The Governor delegates
jobs to his staff while he maintains contact with the public. The Governor
staff obediently performs the work and reports back to the Governor. If
the Governor were to perform every task himself, he would not be able to
give much attention to the public or the press. That's akin to a window
which is busy doing a lengthy job in its primary thread: it doesn't respond
to the user until the job is completed. Such a program can benefit from
creating an additonal thread which is responsible for the lengthy job,
allowing the primary thread to respond to the user's commands.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>We
can create a thread by calling CreateThread function which has the following
syntax:</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><b><font face="Arial,Helvetica"><font color="#FFFFCC"><font size=-1>CreateThread
proto lpThreadAttributes:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FFFFCC"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dwStackSize:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#FFFFCC">lpStartAddress:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FFFFCC"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lpParameter:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FFFFCC"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dwCreationFlags:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#FFFFCC">lpThreadId:DWORD</font></font></font></b><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>CreateThread
function looks a lot like CreateProcess.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">lpThreadAttributes</font></b><font color="#FFFFFF">&nbsp;
--> You can use NULL if you want the thread to have default security descriptor.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">dwStackSize</font></b><font color="#000000">

</font><font color="#FFFFFF">--> specify the stack size of the thread.
If you want the thread to have the same stack size as the primary thread,
use NULL as this parameter.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">lpStartAddress</font></b><font color="#FFFFFF">-->
Address of the thread function.It's the function that will perform the
work of the thread. This function MUST receive one and only one 32-bit
parameter and return a 32-bit value.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">lpParameter</font></b><font color="#000000">&nbsp;</font><font color="#FFFFFF">
--> The parameter you want to pass to the thread function.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">dwCreationFlags</font></b><font color="#FFFFFF">
--> 0 means the thread runs immediately after it's created. The opposite
is CREATE_SUSPENDED flag.</font></font></font>
<br><font face="Arial,Helvetica"><font size=-1><b><font color="#009900">lpThreadId</font></b><font color="#000000">

</font><font color="#FFFFFF">--> CreateThread function will fill the thread
ID of the newly created thread at this address.</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>If
CreateThread call is sucessful, it returns the handle of the newly created
thread. Otherwise, it returns NULL.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>The
thread function runs as soon as CreateThread call is success ful unless
you specify CREATE_SUSPENDED flag in dwCreationFlags. In that case, the
thread is suspended until ResumeThread function is called.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>When
the thread function returns with ret instruction, Windows calls ExitThread
function for the thread function implicitly. You can call ExitThread function
with in your thread function yourself but there' s little point in doing
so.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>You
can retrieve the exit code of a thread by calling GetExitCodeThread function.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>If
you want to terminate a thread from other thread, you can call TerminateThread
function. But you should use this function under extreme circumstance since
this function terminates the thread immediately without giving the thread
any chance to clean up after itself.</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Now
let's move to the communication methods between threads.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>There
are three of them:</font></font></font>
<ul>
<li>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Using
global variables</font></font></font></li>

<li>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Windows
messages</font></font></font></li>

<li>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Event</font></font></font></li>
</ul>
<font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Threads
share the process's resources including global variables so the threads
can use global varibles to communicate with each other. However this method
must be used with care. Thread synchronization must enter into consideration.
For example, if two threads use the same structure of 10 members , what
happens when Windows suddenly yanks the control from one of the thread
when it was in the middle of updating the structure? The other thread will
be left with an inconsistent data in the structure! Don't make any mistake,
multithreading programs are harder to debug and maintain. This sort of
bug seems to happen at random which is very hard to track down.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>You
can also use Windows messages to communicate between threads. If the threads
are all user interface ones, there's no problem: this method can be used
as a two-way communication. All you have to do is defining one or more
custom windows messages that are meaningful to the threads. You define
a custom message by using WM_USER message as the base value say , you can
define it like this:</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font color="#FFFFCC"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
WM_MYCUSTOMMSG equ WM_USER+100h</font></font></font><font face="Arial,Helvetica"><font size=-1></font></font>
<p><font face="Arial,Helvetica"><font color="#FFFFFF"><font size=-1>Windows

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -