Windows编程-线程的创建
2013-07-23 17:03
211 查看
线程描述了进程内代码的执行路径。(这句话怎么理解?)
进程中同时可以有多个线程在执行,为了使它们能够“同时”运行,操作系统为每个线程轮流分配CPU时间片。为了充分利用CPU,提高软件的性能,一般情况下,应用程序使用主线程接受用户的输入,显示运行的结果,而创建新的线程(称为辅助线程)来处理长时间的操作。
每个线程必须有一个入口点函数,线程从入口点开始运行。主线程的入口点是main函数,如果想在进程中创建一个辅助线程,则必须为该辅助线程指定一个入口点函数,这个函数成为线程函数。线程函数的定义如下:
DWORD WINAPI ThreadProc(LPVOID lpParam); //线程函数名称ThreadProc可以使任意的
WINAPI是一个宏名,在windef.h 文件中有如下的声明:
#define WINAPI __stdcall
__stdcall是新标准C/C++函数的调用方法。从底层上说,使用这种调用方法参数的进展顺序和标准C调用(_cdecl方法)是一样的,都是从右到左,但是__stdcall采用自动清栈的方式,而_cedecl采用的是手动清栈的方式。Windows规定,凡是由它来负责调用的函数都必须定义为__stdcall类型。ThreadProc是一个回调函数,即由Windows系统来负责调用的函数,所以此函数应定义为__stdcall类型。注意,如果没有显示说明的话,函数的调用方法是_cdecl。
线程函数只有一个参数lpParam,它的值是由CreateThread函数的第四个参数lpParameter指定的。
创建新线程的函数时CreateThread,由这个函数创建的线程将在调用者的虚拟地址空间内执行。函数用法如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //线程的安全属性
DWORD dwStackSize, //指定线程堆栈的大小
LPTHREAD_START_ROUTINE lpStartAddress, //线程函数的起始地址
LPVOID lpParameter, //传递给线程函数的参数
DWORD dwCreationFlags, //指定创建线程后是否立即启动
DWORD *lpThreadId //用于取得内核给新生成的线程分配的线程ID号
);
此函数成功后,将返回新建线程的线程句柄。lpStartAddress参数指定了线程函数的地址,新建线程将从此地址开始执行,直到return语句返回,线程运行结束,把控制权交给操作系统。
创建线程示例:
#include <stdio.h>
#include <windows.h>
//线程函数
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
int i=0;
while(i<20)
{
printf("%d \r\n",i++);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread;
DWORD dwThreadId;
//创建一个线程
hThread = ::CreateThread(
NULL, //默认安全属性
NULL, //默认堆栈大小
ThreadProc, //线程入口地址(线程函数)
NULL, //传递给线程函数的参数
0, //指定线程创建后立即执行
&dwThreadId); // 返回线程的ID号
printf("Now another thread has been created, ID=%d\n",dwThreadId);
//等待新线程运行结束
::WaitForSingleObject(hThread,INFINITE);
::CloseHandle(hThread);
return 0;
}
进程中同时可以有多个线程在执行,为了使它们能够“同时”运行,操作系统为每个线程轮流分配CPU时间片。为了充分利用CPU,提高软件的性能,一般情况下,应用程序使用主线程接受用户的输入,显示运行的结果,而创建新的线程(称为辅助线程)来处理长时间的操作。
每个线程必须有一个入口点函数,线程从入口点开始运行。主线程的入口点是main函数,如果想在进程中创建一个辅助线程,则必须为该辅助线程指定一个入口点函数,这个函数成为线程函数。线程函数的定义如下:
DWORD WINAPI ThreadProc(LPVOID lpParam); //线程函数名称ThreadProc可以使任意的
WINAPI是一个宏名,在windef.h 文件中有如下的声明:
#define WINAPI __stdcall
__stdcall是新标准C/C++函数的调用方法。从底层上说,使用这种调用方法参数的进展顺序和标准C调用(_cdecl方法)是一样的,都是从右到左,但是__stdcall采用自动清栈的方式,而_cedecl采用的是手动清栈的方式。Windows规定,凡是由它来负责调用的函数都必须定义为__stdcall类型。ThreadProc是一个回调函数,即由Windows系统来负责调用的函数,所以此函数应定义为__stdcall类型。注意,如果没有显示说明的话,函数的调用方法是_cdecl。
线程函数只有一个参数lpParam,它的值是由CreateThread函数的第四个参数lpParameter指定的。
创建新线程的函数时CreateThread,由这个函数创建的线程将在调用者的虚拟地址空间内执行。函数用法如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //线程的安全属性
DWORD dwStackSize, //指定线程堆栈的大小
LPTHREAD_START_ROUTINE lpStartAddress, //线程函数的起始地址
LPVOID lpParameter, //传递给线程函数的参数
DWORD dwCreationFlags, //指定创建线程后是否立即启动
DWORD *lpThreadId //用于取得内核给新生成的线程分配的线程ID号
);
此函数成功后,将返回新建线程的线程句柄。lpStartAddress参数指定了线程函数的地址,新建线程将从此地址开始执行,直到return语句返回,线程运行结束,把控制权交给操作系统。
创建线程示例:
#include <stdio.h>
#include <windows.h>
//线程函数
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
int i=0;
while(i<20)
{
printf("%d \r\n",i++);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread;
DWORD dwThreadId;
//创建一个线程
hThread = ::CreateThread(
NULL, //默认安全属性
NULL, //默认堆栈大小
ThreadProc, //线程入口地址(线程函数)
NULL, //传递给线程函数的参数
0, //指定线程创建后立即执行
&dwThreadId); // 返回线程的ID号
printf("Now another thread has been created, ID=%d\n",dwThreadId);
//等待新线程运行结束
::WaitForSingleObject(hThread,INFINITE);
::CloseHandle(hThread);
return 0;
}
相关文章推荐
- 网络编程(42)—— windows平台下创建线程的四种方法(一)
- windows 多线程编程 之 线程创建
- 网络编程(44)—— windows平台下创建线程的四种方法(三) 工作者线程和CWinThread线程类管理
- windows环境编程: 线程创建函数 设置线程名 隐藏DOS窗口 重定向IO
- 【windows线程】线程资源创建与释放
- windows编程->进程创建
- windows c++程序员开始用linux编程(二)创建新进程
- Windows编程-进程的创建
- 多线程编程-线程的创建和终止
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- Windows编程入门-创建第一个Window窗口
- 多线程编程:分离线程与分离已创建线程
- 走进windows编程的世界-----窗体的注冊及创建
- Windows编程--线程和内核对象的同步-等待定时器内核对象
- 如何:创建和终止线程(C# 编程指南)
- VC多线程编程之线程创建与示例
- 封装创建一个windows下线程
- Windows进程通信——创建线程
- 走进windows编程的世界-----窗口的注册及创建
- Windows编程:计时器的创建