WIN32API,需要包含头文件windows.h
API简介
简单了解下,平时用到的也就那两三个。
接口 | 简介 |
---|---|
SwitchToThread | 切换到另一个可调度线程 |
CreateThread | 创建线程 |
CreateRemoteThread | 创建远程线程 |
GetCurrentThread | 获取线程句柄 |
GetCurrentThreadId | 获取线程ID |
OpenThread | 打开一个现有线程对象 |
SetThreadPriority | 设置线程优先级 |
GetThreadPriority | 获取线程优先级 |
SetThreadPriorityBoost | 设置开关–系统动态提升该线程的优先级 |
GetThreadPriorityBoost | 获取~开关 |
ExitThread | 在线程的执行过程中终止 |
TerminateThread | 在线程的外面终止 |
GetExitCodeThread | 获取一个已中止线程的退出代码 |
SuspendThread | 暂停线程 |
ResumeThread | 恢复线程 |
SetThreadStackGuarantee | 要求系统在抛出EXCEPTION_STACK_OVERFLOW异常的时候,保证仍然有指定大小的空闲区可以用 |
WaitForSingleObject | 阻塞,直到等到信号 |
CloseHandle | 关闭句柄 |
CreateThread导致内存泄漏?
根据百度来的,口水一下。C运行库中有许多全局变量,如错误码等。多个线程同时操作这些全局变量,就会出错(没同步)。为了解决未同步问题,微软想出了个办法,就是给每个线程划分了自己存全局变量的空间,TLS(thread local storage)。这样,各用各的,就不会出错了。奇怪的是,CreateThread压根没TLS的概念,就不会创建这个内存。当在CreateThread创建的线程中要读写那些全局变量时,发现没有TLS,就会创建一个给自己用。可恨的是,CloseHandle中不会释放TLS。这样,内存就泄漏了。所以,为了保险起见,创建线程使用C运行库中的_beginthreadex。
测试,通过监视程序内存,确实发现内存缓慢增长。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24DWORD g_id = 0; DWORD WINAPI fun1(void* param) { int i = errno; //使用C运行时变量 Sleep(20); //确保线程返回有效句柄 //_endthreadex(g_id); //即使加上这句也会内存泄漏 return 0; } int main() { while (1) { HANDLE handle = CreateThread(nullptr, 0, &fun1, nullptr, THREAD_RESUME, &g_id); WaitForSingleObject(handle, INFINITE); //等当前线程自然结束 CloseHandle(handle); } return 0; }
SuspendThread的计数规则
在测试中,对一个线程连续SuspendThread三次,然后ResumeThread一次,发现线程没有被唤醒。直到再ResumeThread两次后,线程才被唤醒。估计线程内有个计数,SuspendThread一次加一,ResumeThread一次减一。0表示线程可以执行啦,求CPU来拥抱。
自定义一个实用的线程类
一个理想的线程,当然是希望它自然退出,不能自然退出视为逻辑BUG。同时,能控制线程运行,挂起,唤醒和结束。至于优先级之类的,貌似手动设置不如系统优化。
公有方法
1
2
3
4
5
6
7
8
9//启动,线程初始状态为暂停。 bool play(); //暂停,同一线程,最多被SuspendThread一次。 bool pause(); //结束,若是暂停状态,先启动再让其自然退出。 bool stop(); //当前状态,启动|暂停|结束 eState getState();
完整源码(也可下载完整测试工程)
.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#pragma once typedef void(*proc_type)(void*); class ThreadWin { public: enum eState { PLAY = 1, PAUSE, STOP }; friend unsigned __stdcall threadWinProc(void* param); ThreadWin(proc_type proc, void* param); ~ThreadWin(); //启动 bool play(); //暂停 bool pause(); //结束 bool stop(); //当前状态 eState getState(); private: //禁止拷贝 ThreadWin(const ThreadWin &) = delete; //禁止赋值 ThreadWin& operator=(const ThreadWin &) = delete; private: proc_type m_proc; //线程执行函数 void* m_param; //执行函数参数 eState m_state; //线程状态 unsigned m_handle; //线程句柄 unsigned m_id; //线程ID };
.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98#include "ThreadWin.h" #include <windows.h> #include <process.h> static unsigned __stdcall threadWinProc(void* param) { ThreadWin* th = (ThreadWin*)param; while (ThreadWin::STOP != th->m_state) { th->m_proc(th->m_param); } return 0; } ThreadWin::ThreadWin(proc_type proc, void* param) : m_proc(proc) , m_param(param) , m_state(PAUSE) { //err: 0 m_handle = _beginthreadex(NULL, 0, threadWinProc, this, CREATE_SUSPENDED, &m_id); } ThreadWin::~ThreadWin() { stop(); } bool ThreadWin::play() { if (0 == m_handle || STOP == m_state) { return false; } DWORD ret = ResumeThread((HANDLE)m_handle); if (-1 == ret) { return false; } m_state = PLAY; return true; } bool ThreadWin::pause() { if (0 == m_handle || STOP == m_state) { return false; } if (PAUSE == m_state) { return true; } DWORD ret = SuspendThread((HANDLE)m_handle); if (-1 == ret) { return false; } m_state = PAUSE; return true; } bool ThreadWin::stop() { if (0 == m_handle) { return false; } if (PAUSE == m_state) { bool ret = play(); if (!ret) { return false; } } m_state = STOP; WaitForSingleObject((HANDLE)m_handle, INFINITE); CloseHandle((HANDLE)m_handle); m_handle = 0; return true; } ThreadWin::eState ThreadWin::getState() { return m_state; }
最后
以上就是缓慢大神最近收集整理的关于C++多线程之CreateThread的全部内容,更多相关C++多线程之CreateThread内容请搜索靠谱客的其他文章。
发表评论 取消回复