我是靠谱客的博主 缓慢大神,这篇文章主要介绍C++多线程之CreateThread,现在分享给大家,希望可以做个参考。

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
24
DWORD 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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部