转载(原文地址):VS2010 多线程编程
此时在多核CPU下,主线程和子线程可同时运行;
#include
#include
#include
using namespace std;
DWORD WINAPI MyThreadProc1(LPVOID lpParameter);
DWORD WINAPI MyThreadProc2(LPVOID lpParameter);
int index = 0;
int i = 0 , y = 0;
int main()
{
HANDLE handle1,handle2;
handle1 = CreateThread(NULL,0,MyThreadProc1,NULL,0,NULL);
handle2 = CreateThread(NULL,0,MyThreadProc2,NULL,0,NULL);
if(NULL == handle1)
{
cout<<"Create Thread failed !"<return -1;
}
if(NULL == handle2)
{
cout<<"Create Thread failed !"<return -1;
}
CloseHandle(handle1);
CloseHandle(handle2);
cout<<"The Main Thread is Running !"<"PAUSE");
return 0;
}
DWORD WINAPI MyThreadProc1(LPVOID lpParameter)
{
cout<<"The MyThreadProc1 is Running !"<return 0;
}
DWORD WINAPI MyThreadProc2(LPVOID lpParameter)
{
cout<<"The MyThreadProc2 is Running ! "<return 0;
}
虽然cpu是多核的很久了,但是很多时候都是串行执行,降低了执行的速率。因为项目需要开启额外线程进行信号的获取。(下篇决定学习一下并行执行)
创建线程貌似此函数就够了,只知道第三个参数是函数参数
handle1 = CreateThread(NULL,0,MyThreadProc1,NULL,0,NULL);
创建线程具体参数详解:http://www.cnblogs.com/del/category/174761.html
函数原型
function CreateThread(
lpThreadAttributes: Pointer; {安全设置}
dwStackSize: DWORD; {堆栈大小}
lpStartAddress: TFNThreadStartRoutine; {入口函数}
lpParameter: Pointer; {函数参数}
dwCreationFlags: DWORD; {启动选项}
var lpThreadId: DWORD {输出线程 ID }
): THandle; stdcall; {返回线程句柄}
对象 | 区别 |
---|---|
句柄 | 只是使用对象-有句柄的对象一般都是系统级别的对象(或叫内核对象)-一般把句柄提交到某个函数(一般是系统函数)后 |
指针 | 可读写对象 |
相同点 | 内存中的一小块数据(一般用结构描述), |
2. 参数1:安全设置
lpThreadAttributes 是指向 TSecurityAttributes 结构的指针, 一般都是置为 NULL(没有访问限制)
3. 参数2:堆栈大小(栈:私有的||堆:公用的)
每个线程都有自己独立的堆栈(也拥有自己的消息队列).默认值是 0, 这表示使用系统默认的大小, 默认和主线程栈的大小一样, 如果不够用会自动增长;
对象 | 不同点 | 用途 |
---|---|---|
堆 | 先进先出 | |
栈(堆栈) | 先进后出 | 适合存取临时而轻便的变量, 主要用来储存局部变量; |
相同点 | 都是进程中的内存区域 |
4. 参数3:入口函数指针(即函数地址)
入口函数的标准定义, 这个函数的标准返回值应该是 DWORD。(可以通过退出码来判断线程是否已退出.)
线程退出后, 我们用 GetExitCodeThread 函数获取的退出码就是这个返回值!
如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量 STILL_ACTIVE (259);
5. 参数4:函数参数
线程入口函数的参数是个无类型指针(Pointer), 用它可以指定任何数据;
6. 参数5:启动选项
CreateThread 的倒数第二个参数 dwCreationFlags(启动选项) 有两个可选值:
0: 线程建立后立即执行入口函数;
CREATE_SUSPENDED: 线程建立后会挂起等待.
ResumeThread 恢复线程的运行;
SuspendThread 挂起线程.
这两个函数的参数都是线程句柄, 返回值是执行前的挂起计数.
PS:挂起计数(count≥0)
SuspendThread ,count+=1;
ResumeThread ,count -=1;
if count == 0 , 线程run; > 0 时会挂起.
如果被 SuspendThread 多次, 同样需要 ResumeThread 多次才能恢复线程的运行.
ResumeThread 和 SuspendThread 分别对应 TThread 的 Resume 和 Suspend 方法, 很好理解.
7. 参数6:输出线程ID
ID 比句柄更轻便.在主线程中 GetCurrentThreadId、MainThreadID获取的都是主线程的 ID |
---|
线程的 ID 是唯一的; 而句柄可能不只一个, 譬如可以用 GetCurrentThread 获取一个伪句柄、可以用 DuplicateHandle 复制一个句柄等等. |
ID 比句柄更轻便.在主线程中 GetCurrentThreadId、MainThreadID获取的都是主线程的 ID. |