sin的博客

时间悄悄地流过,今天你做了什么
posts - 17, comments - 3, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

WIN32多线程一 用WIN32 API创建和结束线程

Posted on 2010-02-22 11:15 sin 阅读(4116) 评论(2)  编辑 收藏 引用 所属分类: WIN32编程
Win32中,内核对象属于WINDOWS的,而不属于进程。进程对象、线程对象、文件对象、文件映射对象、事件对象、互斥量对象等都属于内核对象。WIN32中一般通过CreateXXXX来创建内核对象,返回一个内核对象的句柄,进程不能直接操作内核对象,只能通过该句柄来访问内核对象。内核对象有一个使用计数,一个进程的内核对象句柄表中引用了某个内核对象,该内核对象的使用计数就递增1,该进程调用CloseHandle时,引用计数递减,当引用计数为0时,内核对象被销毁,当进程退出时,进程所引用内核对象的引用计数都递减1。

线程也是内核对象,当创建一个线程时,默认引用计数是2。调用CloseHandle时,线程引用计数下降1;当线程结束时,引用计数再下降1。仅仅调用CloseHandle并不能保证线程结束。利用这个特点,我们可以在调用CloseHandle前用GetExitCodeThread获得线程的结束代码,如果线程是STILL_ACTIVE状态,表示线程尚未结束。下面是一个能保证线程正常结束例子:

不过例子中等待线程结束的方法非常笨,用一个for循环不断检测线程状态,如果两个线程都结束了,才跳出循环,更好的方法是WaitForSigleObject,后面介绍。

 1 /*
 2  * ExitCode.c
 3  *
 4  * Sample code for "Multithreading Applications in Win32"
 5  * This is from Chapter 2, Listing 2-2
 6  *
 7  * Start two threads and try to exit
 8  * when the user presses a key.
 9  */
10 
11 #define WIN32_LEAN_AND_MEAN
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <windows.h>
15 #include <conio.h>
16 
17 DWORD WINAPI ThreadFunc(LPVOID);
18 
19 int main()
20 {
21     HANDLE hThrd1;
22     HANDLE hThrd2;
23     DWORD exitCode1 = 0;
24     DWORD exitCode2 = 0;
25     DWORD threadId;
26     
27     hThrd1 = CreateThread(NULL,
28         0,
29         ThreadFunc,
30         (LPVOID)1,
31         0,
32         &threadId );
33     if (hThrd1)
34         printf("Thread 1 launched\n");
35 
36     hThrd2 = CreateThread(NULL,
37         0,
38         ThreadFunc,
39         (LPVOID)2,
40         0,
41         &threadId );
42     if (hThrd2)
43         printf("Thread 2 launched\n");
44 
45 
46     // Keep waiting until both calls to
47     // GetExitCodeThread succeed AND
48     // neither of them returns STILL_ACTIVE.
49     // This method is not optimal - we'll
50     // see the correct way in Chapter 3.
51     for (;;)
52     {
53         printf("Press any key to exit..\n");
54         getch();
55 
56         GetExitCodeThread(hThrd1, &exitCode1);
57         GetExitCodeThread(hThrd2, &exitCode2);
58         if ( exitCode1 == STILL_ACTIVE )
59             puts("Thread 1 is still running!");
60         if ( exitCode2 == STILL_ACTIVE )
61             puts("Thread 2 is still running!");
62         if ( exitCode1 != STILL_ACTIVE
63             && exitCode2 != STILL_ACTIVE )
64             break;
65     }
66 
67     CloseHandle(hThrd1);
68     CloseHandle(hThrd2);
69 
70     printf("Thread 1 returned %d\n", exitCode1);
71     printf("Thread 2 returned %d\n", exitCode2);
72 
73     return EXIT_SUCCESS;
74 }
75 
76 
77 /*
78  * Take the startup value, do some simple math on it,
79  * and return the calculated value.
80  */
81 DWORD WINAPI ThreadFunc(LPVOID n)
82 {
83     Sleep((DWORD)n*1000*2);
84     return (DWORD)n * 10;
85 }

线程也可以自己结束掉自己,方法是调用ExitThread。尽量不在主线程中调用ExitTread,这样会强制其他线程终止,进程终止,而其他线程没有机会做清理工作。

Feedback

# re: WIN32多线程一 用WIN32 API创建和结束线程  回复  更多评论   

2011-06-08 16:13 by
你牛逼

# re: WIN32多线程一 用WIN32 API创建和结束线程  回复  更多评论   

2013-11-09 12:14 by LGC
有帮助,感谢

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理