Tài liệu thực hành môn Mạng máy tính - Bài: Lập trình đa tiểu trình - Thread

Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
Lp trình đa tiu trình - Thread  
1.  
2.  
Mc tiêu  
SV tiếp cn bài toán đa tiu trình và các thao tác trên tiu trình.  
Đặt vn đề  
Gista có n (n ³ 2) công vic và mun thc hin n công vic này đồng thi. Có  
nhiu cách gii quyết vn đề này, trong bài này sgii thiu mt gii pháp là ddng  
thread, mi thread sthc thi mt công vic và thc thi song song vi các công vic  
còn li.  
3.  
To và hy tiu trình  
1.1. Gii thiu bài toán  
Hãy viết chương trình theo kiu bm gibng cách mi ln nhn mt phím thì sẽ  
in ra snhp đã trôi qua tkhi chương trình bt đầu chy, vi mi nhp bng 100ms,  
chương trình skết thúc khi nhn ESC. Vi hàm sdng là hàm _getch, quyn điu  
khin skhông được trli cho đến khi có mt phím được nhn, ta skhông ththc  
hin vic tăng biến đếm sau mi nhp.  
Có nhiu cách tiếp cn để gii quyết yêu cu. Có thdùng cơ chế Timer nhưng  
vn cn phi có mt lung (tiu trình) khác để nhn WM_TIMER. Hoc có thkim tra  
chkhi nào phím đã được nhn mi gi hàm _getch, cách này khá phc tp và không hiu  
qukhi yêu cu bài toán không chđếm gimà còn phi đọc đĩa, tương tác vi mng...  
1.2. Tiếp cn bài toán theo hướng đa lung  
Gista có 2 lung thc hin 2 công vic riêng bit (ging như 2 người làm 2  
nhim vriêng bit) như sau:  
+ Lung CounterThread: thc hin tăng biến đếm nCount, delay trong  
100ms, ri li tăng biến đếm nCount...  
while (!bESCPressed)  
{
nCount++;  
Sleep(100);  
}
+ Lung GetKeyThread: nhn mt phím bng hàm _getch, in giá trbiến  
đếm nCount, ri li nhn mt phím _getch... cho đến khi phím ESC được nhn.  
do {  
bESCPressed = (_getch() == 27);  
printf("%d\n", nCount);  
- 1 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
} while (!bESCPressed);  
Rõ ràng vi vic sdng 2 lung cho bài toán trên, vn đề trnên đơn gin.  
1.3. Điu kin để mt chương trình VC++ chy được chế độ đa lung  
Nhn Alt-F7 để vào trong Project\Settings...  
Nếu như chế độ Use run-time library: đang để ở Single-Threaded hoc Debug  
Single-Threaded thì phi chuyn sang chế độ Multithreaded tương ng là Multithreaded  
và Debug Multithreaded.  
chuyn  
thành ==>  
Cách to mt tiu trình mi trong Visual C++  
Trong Windows để khi động mt lung mi, thì ta phi cài đặt lung đó trong  
mt hàm, khi hàm kết thúc thì lung được to cũng tkết thúc.  
Để to mt lung mi ta dùng hàm CreateThread  
HANDLE CreateThread  
- 2 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
{
SEC_ATTRS SecurityAttributes,  
ULONG StackSize,  
SEC_THREAD_START StartFunction,  
PVOID ThreadParameter,  
ULONG CreationFlags,  
PULONG ThreadId  
};  
Trong đó:  
SecurityAttributes: trỏ đến cu trúc SECURITY_ATTRIBUTES dùng để xác định  
handle ca tiến trình mi to có được kế tha bi các tiến trình con không. Chú ý: trong  
Windows 9x nếu tham snày mang giá trNULL thì handle này không thkế tha bi  
tiến trình con khác, trong Windows NT nếu mang giá trNULL có nghĩa là tiu trình này  
sdng chế độ an toàn mc định.  
dwStackSize: kích thước ban đầu ca stack cc bca tiu trình.Nếu có giá tr0  
hay nhhơn kích thước mc định thì hthng dùng kích thước ca tiu trình to và tự  
đng tăng kích thước khi cn. Nếu không đủ bnhthì hàm to tiu trình mi stht bi.  
Vùng stack này tự động được gii phóng khi tiu trình kết thúc.  
lpStartAddress: tên hàm mô tcông vic mà tiu trình cn thc hin. Hàm này  
được khai báo như sau:  
DWORD WINAPI ThreadProc(LPVOID lpParameter);  
lpParameter: tham số được truyn cho tiu trình. Lưu ý: tham struyn vào phi  
ép kiu thành LPVOID sau đó vô hàm ép kiu ngược trli.  
dwCreationFlags: qui định trng thái tiu trình khi mi to lp. Nếu mang giá tr0,  
tiu trình to ra sthc thi ngay; nếu là CREATE_SUSPENDED , tiu trình schcho  
đến khi gi hàm ResumeThread.  
lpThreadId: con trnhn giá trtrvlà ID ca tiu trình.  
Nếu thành công, nhn giá trtrvlà handle ca tiu trình. Ngược li nhn giá trị  
NULL.  
Mi tiu trình sau khi được to đều có cùng độ ưu tiên mc định là  
THREAD_PRIORITY_NORMAL. Ta có ththay đổi hay xác định bng hàm  
SetThreadPriority và GetThreadPriority.  
hoc sdng hàm:  
CWinThread* AfxBeginThread(  
AFX_THREADPROC pfnThreadProc,  
LPVOID pParam,  
int nPriority = THREAD_PRIORITY_NORMAL,  
UINT nStackSize = 0,  
DWORD dwCreateFlags = 0,  
- 3 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );  
CWinThread* AfxBeginThread(  
CRuntimeClass* pThreadClass,  
int nPriority = THREAD_PRIORITY_NORMAL,  
UINT nStackSize = 0,  
DWORD dwCreateFlags = 0,  
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );  
Trong đó:  
pfnThreadProc: tên hàm mô tcông vic mà tiu trình cn thc hin.  
UINT MyControllingFunction( LPVOID pParam );  
pParam: tham số được truyn cho tiu trình.  
nPriority: độ ưu tiên ca thread.  
pThreadClass: tên lp kế tha tCWinThread.  
Hàm này trvcon trkiu CWinThread nếu thành công, ngược li trvNULL  
Ví d: khi mun to tiu trình CouterThread, ta thc hin  
Cách 1:  
Hàm CounterThread được cài đặt như sau:  
DWORD WINAPI CounterThread(LPVOID /*pParam*/)  
{
while (!bESCPressed) {  
nCounter++;  
Sleep(100);  
}
return 0;  
}
do pParam ít sdng nên ta không cn khai báo để tránh bli warning  
// to thread  
DWORD dwThreadIdCounter;  
HANDLE hThreadCounter;  
hThreadCounter = CreateThread(NULL, 0,  
CounterThread, NULL, 0, &dwThreadIdCounter);  
Cách 2:  
// hàm xlý thread cài đặt ging cách 1  
// to thread  
CWinThread *h1;  
h1 = AfxBeginThread((AFX_THREADPROC) CounterThread, NULL,  
THREAD_PRIORITY_NORMAL,0,0,NULL);  
- 4 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
Cách 3: to 1 lp kế tha tCWinThread: CCounterThread, khi đó hàm Run (add  
virtual function) scha đon code xlý thread  
// Hàm Run ca lp CCounterThread được cài đặt như sau:  
int CCounterThread::Run()  
{
// TODO: Add your specialized code here and/or call the base class  
while (!bESCPressed)  
{
nCounter++;  
Sleep(100);  
}
return CWinThread::Run();  
}
// to thread  
CCounterThread* h1;  
h1 = (CCounterThread*)AfxBeginThread(RUNTIME_CLASS(CCounterThread),  
THREAD_PRIORITY_NORMAL,0,0,NULL);  
- 5 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
1.4. Thay đổi trng thái ca tiu trình  
( 2 )  
( 3 )  
( 1 )  
( 4 )  
Môùi taïo  
Running  
( 6 )  
Keát thuùc  
Ready  
( 5 )  
Sleeping  
Waiting  
( 8 )  
( 7 )  
( 10 )  
( 9 )  
Suspended  
( 11 )  
1.4.1. Hàm tm dng 1 tiu trình  
DWORD  
SuspendThread  
{
HANDLE hThread  
};  
Trong đó:  
hThread: handle ca tiu trình mun tm dng  
Hàm SuspendThread tm dng hot động ca 1 tiu trình. Giá trtrvsln yêu cu  
tm dng (suspend count) trước khi tăng hoc 0xFFFFFFFF nếu có li. (suspend count sẽ  
được tăng lên 1 mi ln yêu cu tm dng tiu trình).  
1.4.2. Hàm Hutrng thái tm dng ca 1 tiu trình  
DWORD  
{
ResumeThread  
HANDLE hThread  
};  
- 6 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
Trong đó:  
hThread: handle ca tiu trình mun hutrng thái tm dng  
Hy btrng thái tm dng ca 1 tiu trình bng cách kim tra giá trca sln  
yêu cu tm dng (suspend count), nếu suspend count > 0 , thì sgim đi 1 để hub1  
ln yêu cu tm dng tiu trình tương ng, khi suspend count = 0, ResumeThread skhôi  
phc li hot động ca tiu trình. Giá trtrvca hàm này là suspend count lúc chưa  
gim hoc 0xFFFFFFFF nếu có li.  
1.5. Kết thúc mt tiu trình  
Ngoài vic mt tiu trình tkết thúc khi hàm cài đặt ca tiu trình kết thúc, ta còn  
có thyêu cu tiu trình kết thúc tc thi. Tuy nhiên, vic kết thúc hàm theo kiu “thô  
bo” như vy sdn đến vic không hy bỏ đúng đắn nhng tài nguyên đã được cp như  
mfile, kết ni mng...  
Kết thúc tiu trình hin hành: dùng hàm ExitThread(dwExitCode) trong đó  
dwExitCode là mã li trv, thường là bng 0.  
Để kết thúc mt tiu trình khác ta phi có handle ca tiu trình đó (hThread) được  
trvkhi to tiu trình, khi đó dùng hàm TerminateThread(hThread, dwExitCode) để  
kết thúc mt tiu trình.  
1.6. Các hàm khác  
GetThreadTimes  
BOOL  
{
GetThreadTimes  
HANDLE  
hThread,  
LPFILETIME  
LPFILETIME  
LPFILETIME  
LPFILETIME  
lpCreationTime,  
lpExitTime,  
lpKernelTime,  
lpUserTime  
};  
Trvthi đim to lp tiu trình lpCreationTime, thi đim kết thúc tiu trình  
lpExitTime, thi gian tiu trình hot động trong chế độ User lpUserTime, trong chế độ  
Kernel lpKernelTime ca tiu trình hThread.  
Hàm GetExitCodeThread  
BOOL  
{
GetExitCodeThread  
HANDLE hThread,  
- 7 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
LPDWORD lpExitCode  
};  
Xác định trng thái kết thúc ca tiu trình hThread. Nếu tiu trình đang hot động,  
ExitCode nhn giá trSTILL_ACTIVE.  
Hàm GetCurrendThreadId  
HANDLE GetCurrentThreadId (void);  
Trvề định danh duy nht ca tiu trình đang hot động.  
Hàm GetCurrentThread  
HANDLE GetCurrentThread (void);  
Trvhandle ca tiu trình đang hot động.  
Lưu ý:  
§ Đối vi lp CWinThread, các hàm trên đều là hàm thuc lp cWinThread chcó  
hàm Terminate là không có. Tuy nhiên, có ththao tác bình thường vi các thread  
đó thong qua hThread trong lp CWinThread.  
§ Trong môi trường C#, các bn ssdng lp Thread trong  
System.Threading.Thread, sdng các hàm: Start, ThreadStart, Resume, Suspend,  
Abort…. (tham kho thêm VD trong MSDN)  
4.  
Bài tp  
Bài tp 1: Viết chương trình tăng gim s. Chương trình gm có 2 tiu trình, tiu  
trình thnht thc hin vic tăng giá trca biến x, trình thhai thc hin vic gim giá  
trca biến x. Sau khi tăng gim xong xut ni dung ca biến đó ra màn hình.  
Bài tp 2: Viết chương trình chương trình hin th10 ký tngu nhiên trên màn  
hình, mi ký tự được qun lý bi mt tiu trình và di chuyn liên tc vi tc độ tùy ý.  
Khi di chuyn nếu chm biên màn hình thì ký tsxut hin li ti gia màn hình.  
Chương trình kết thúc khi người dùng nhn phím bt k.  
Bài tp 3: Viết chương trình to ra 3 tiu trình, mi tiu trình qun lý mt ô vuông  
có màu khác nhau di chuyn tdo trên màn hình. Chương trình cho phép start, stop,  
suspend, resume, set priority tng tiu trình.  
Bài tp 4: Viết chương trình có 1 du * di chuyn chéo trên màn hình, khi gp  
biên du * này sdi li (phn x). Tc độ di chuyn gia 2 ô kế nhau là 500ms. Khi  
người dùng nhn các phím ↑↓←→ hoc các phím W, Z, A, S thì ngay lp tc du * sdi  
chuyn lên trên, xung dưới, sang trái, sang phi. Chương trình kết thúc khi người dùng  
nhn phím ESC.  
- 8 -  
Bmôn Mng máy tính và Vin thông  
Khoa CNTT – Trường ĐH KHTN Tp. HCM  
Bài tp 5: Viết chương trình cun chui. Chương trình có hai tiến trình thc hin  
thao tác sau: tiến trình thnht thc hin thao tác cun chui, tiến trình thhai xut  
chui đang cun ra màn hình.  
Lưu ý:  
§ Các bài tp không đặt nng giao din, chyêu cu hiu được cách to thread  
và các thao tác trên thread.  
§ Đối vi bài 1, 5: các bn nên làm trên Console.  
§ Đối vi các bài tp 2,3,4 nếu các bn làm trên Console, các bn xem thêm  
file hướng dn console.doc để biết cách xut 1 ký tra màn hình ti 1 toạ  
độ xy. Nếu làm trên MFC, các bn làm dng View (Single Document)  
Các câu hi thường gp khi to thread:  
1. Trong console, to thread nhưng thread không chy.  
Trli: do hàm main sau khi to thread xong kết thúc luôn chương trình è tt cả  
các tiu trình đều kết thúc.  
2. Truyn nhiu tham svào trong 1 thread.  
Trli: nếu mun truyn nhiu tham svào trong 1 thread thì phi to 1 struct  
cha các tham số đó sau đó truyn struct đó vào hàm.  
MyStruct b;  
b = *(MyStruct*)lp; // chcn ly ni dung ca tham struyn vào  
AfxBeginThread((AFX_THREADPROC)CounterThread,(LPVOID)&b,  
THREAD_PRIORITY_NORMAL,0,0,NULL);  
Nếu sdng lp CWinThread, bn nên add các biến thành viên cho lp và gán trị  
trược tiếp. Khi đó, bn cn to thread vi clà CREATE_SUNSPENDED sau đó gi  
hàm ResumeThread  
- 9 -  
pdf 9 trang myanh 17820
Bạn đang xem tài liệu "Tài liệu thực hành môn Mạng máy tính - Bài: Lập trình đa tiểu trình - Thread", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdftai_lieu_thuc_hanh_mon_mang_may_tinh_bai_lap_trinh_da_tieu_t.pdf