_beginthread
和_beginthreadex
是Windows下创建线程的函数。
结束线程函数_endthread
和_endthreadex
。
主线程结束了,子线程也会结束。
_beginthread
函数原型
/** \brief 创建一个线程
*
* \param start_address 新线程的起始地址 ,指向新线程调用的函数的起始地址
* \param stack_size 新线程的堆栈大小,可以为0
* \param arglist 传递给线程的参数列表,无参数时为NULL,多参数的时候可以传入结构体
* \return 成功,函数将会返回一个新线程的句柄
* 失败_beginthread将返回-1
* 如 th1 = (HANDLE)_beginthread(Thread1, 0, NULL);
*
*/
uintptr_t _beginthread(void(*start_address)(void*),
unsigned stack_size,
void* arglist);
另uintptr_t
的类型为unsigned long long
typedef unsigned __int64 uintptr_t;
_beginthreadex
函数原型
/** \brief 创建一个线程
*
* \param security 安全属性, 为 NULL时表示默认安全性
* \param stack_size 新线程的堆栈大小,一般默认为0
* \param start_address 指定线程函数,也就是线程调用执行的函数地址
* \param arglist 传递给线程的参数列表,无参数时为 NULL,多参数的时候可以传入结构体
* \param initflag 新线程的初始状态,0表示立即执行,CREATE_SUSPENDED表示创建之后挂起
* \param threaddr 指向接收线程标识符的 32 位变量。
如果是 NULL ,则不使用
* \return 成功,函数将会返回一个新线程的句柄
* 发生错误时, _beginthreadex 返回 0 并设置 errno 和 _doserrno
*
*/
uintptr_t _beginthreadex(void* security,
unsigned stack_size,
unsigned(_stdcall* start_address)(void*),
void* argilist,
unsigned initflag,
unsigned* threaddr);
_endthread
函数原型
/** \brief 终止线程
*
* \param 无
* \return 无
*
*/
void _endthread(void);
注意:
_endthread
会自动关闭线程句柄。(该行为与 Win32 ExitThread API 不同。
) 因此,当你使用
_beginthread
和_endthread
时,不要通过调用 Win32CloseHandle
API 来显式关闭线程句柄。
_endthreadex
函数原型
/** \brief 终止线程
*
* \param retval 线程退出代码
* \return 无
*
*/
void _endthreadex(unsigned retval);
示例1注意:
_endthreadex
不会关闭线程句柄。因此,当你使用
_beginthreadex
和_endthreadex
时,必须通过调用 Win32CloseHandle
API 来关闭线程句柄。
#include
#include
#include
/* 线程函数声明 */
void Thread1(void*);
void Thread2(void*);
//unsigned int __stdcall Thread1ex(void*);
//unsigned int __stdcall Thread2ex(void*);
/* 线程句柄 */
HANDLE h1, h2;
/* 线程共享内存 */
volatile int i = 0;
/* 主线程 */
int main()
{
/* 创建线程 */
h1 = (HANDLE)_beginthread(Thread1, 0, NULL);//线程1
h2 = (HANDLE)_beginthread(Thread2, 0, NULL);//线程2
//h1 = (HANDLE)_beginthreadex(NULL, 0, Thread1ex, NULL, 0, NULL);
//h2 = (HANDLE)_beginthreadex(NULL, 0, Thread2ex, NULL, 0, NULL);
WaitForSingleObject(h1, INFINITE);//等待线程1结束
WaitForSingleObject(h2, INFINITE);//等待线程2结束
//system("pause");
printf("主线程结束\n");
return 0;
}
/* 线程1 */
void Thread1(void* arg)
{
while (1)
{
printf("Thread1\n");
Sleep(100);
}
}
/* 线程2 */
void Thread2(void* arg)
{
while (1)
{
printf("Thread2\n");
Sleep(100);
}
}
///* 线程1 */
//unsigned int __stdcall Thread1ex(void* arg)
//{
// while (1)
// {
// printf("Thread1\n");
// Sleep(100);
// }
//}
//
//
///* 线程2*/
//unsigned int __stdcall Thread2ex(void* arg)
//{
// while (1)
// {
// printf("Thread2\n");
// Sleep(100);
// }
//}
输出结果
/** \brief 等待函数 – 使线程进入等待状态,直到指定的内核对象被触发。
*
* \param hHandle 要等待的内核对象
* \param dwMilliseconds 最长等待的时间,以毫秒为单位;传入0就立即返回,传入INFINITE表示无限等待
* \return 在指定的时间内对象被触发,函数返回WAIT_OBJECT_0
* 超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。
传入参数有错误将返回WAIT_FAILED
*
*/
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。
对应的还有一个函数
WaitForMultipleObjects/** \brief 等待函数 – 使线程进入等待状态,直到指定的内核对象被触发。
*
* \param nCount lpHandles指向的数组中的对象句柄数。
对象句柄的最大数量为MAXIMUM_WAIT_OBJECTS。
此参数不能为零
* \param lpHandles 一组对象句柄。
该数组可以包含不同类型对象的句柄。
它可能不包含同一句柄的多个副本
* 如果其中一个句柄在等待仍处于暂挂状态时关闭,则该函数的行为未定义
* \param bWaitAll 如果此参数为TRUE,则在lpHandles数组中的所有对象的状态发出信号时,该函数返回。
如果为FALSE,则当任何一个对象的状态设置为信号时,该函数返回
在后一种情况下,返回值表示其状态导致函数返回的对象。
* \param dwMilliseconds 最长等待的时间,以毫秒为单位;传入0就立即返回,传入INFINITE表示无限等待
* \return 返回WAIT_OBJECT_0则返回值表明所有指定对象的状态信号
* 超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。
传入参数有错误将返回WAIT_FAILED
*
*/
DWORD WaitForMultipleObjects(DWORD nCount,
const HANDLE* lpHandles,
BOOL bWaitAll,
DWORD dwMilliseconds
);
示例2
线程1与线程2通过共享内存来通讯。
#include
#include
#include
/* 线程函数声明 */
//void Thread1(void*);
//void Thread2(void*);
unsigned int __stdcall Thread1ex(void*);
unsigned int __stdcall Thread2ex(void*);
/* 线程句柄 */
HANDLE h1, h2;
/* 线程共享内存 */
volatile int i = 0;
/* 主线程 */
int main()
{
/* 创建线程 */
//h1 = (HANDLE)_beginthread(Thread1, 0, NULL);//线程1
//h2 = (HANDLE)_beginthread(Thread2, 0, NULL);//线程2
h1 = (HANDLE)_beginthreadex(NULL, 0, Thread1ex, NULL, 0, NULL);
h2 = (HANDLE)_beginthreadex(NULL, 0, Thread2ex, NULL, 0, NULL);
while (1)
{
printf("Main Thread\n");
Sleep(100);
}
system("pause");
return 0;
}
///* 线程1 */
//void Thread1(void* arg)
//{
// while (1)
// {
// printf("Thread1\n");
// Sleep(100);
// }
//}
//
//
///* 线程2 */
//void Thread2(void* arg)
//{
// while (1)
// {
// printf("Thread2\n");
// Sleep(100);
// }
//}
/* 线程1 */
unsigned int __stdcall Thread1ex(void* arg)
{
while (1)
{
i++;
Sleep(100);
}
}
/* 线程2*/
unsigned int __stdcall Thread2ex(void* arg)
{
while (1)
{
printf("i = %d\n", i);
Sleep(100);
}
}
输出结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)