Windows创建线程与事件示例以及信号设置

1、# Windows创建线程与事件示例

  • 初始化事件以及清理事件
void CSDOLApp::InitializeEvents() 
{
	TRACET();
	g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (g_hStopEvent == NULL) 
	{
		// 错误处理
	}
}

void CSDOLApp::CleanupEvents() 
{
	TRACET();
	if (g_hStopEvent != NULL) 
	{
		CloseHandle(g_hStopEvent);
		g_hStopEvent = NULL;
	}
}
  • 这段代码是 CSDOLApp 类中的两个函数,分别用于初始化和清理事件对象 g_hStopEvent
    1. InitializeEvents 函数:
      • 这个函数的作用是初始化事件对象 g_hStopEvent
      • 首先,在函数开始处输出了一条日志,标识函数开始执行。
      • 然后调用 CreateEvent 函数创建一个事件对象,并将其赋值给全局变量 g_hStopEvent
      • 如果 CreateEvent 函数返回的事件对象句柄为 NULL,表示创建事件失败,这时候可能会执行一些错误处理代码(注释中的错误处理部分),具体处理方式根据实际情况而定。
    2. CleanupEvents 函数:
      • 这个函数的作用是清理事件对象 g_hStopEvent
      • 首先,在函数开始处输出了一条日志,标识函数开始执行。
      • 然后检查全局变量 g_hStopEvent 是否为 NULL,如果不为 NULL,则调用 CloseHandle 函数关闭事件对象,并将 g_hStopEvent 设置为 NULL,以确保不再使用已关闭的句柄。
  • 总的来说,InitializeEvents 函数用于创建事件对象,CleanupEvents 函数用于关闭事件对象。这两个函数通常会在程序的启动和结束阶段调用,以确保事件对象的正确创建和释放。
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateEventW(
    __in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
    __in     BOOL bManualReset,
    __in     BOOL bInitialState,
    __in_opt LPCWSTR lpName
    );
#ifdef UNICODE
#define CreateEvent  CreateEventW
#else
#define CreateEvent  CreateEventA
#endif // !UNICODE
  • 这段代码是 Windows API 中的 CreateEvent 函数的声明及一些说明。

    • CreateEvent 函数用于创建一个事件对象,并返回一个句柄以供后续操作。它的参数包括:

      • lpEventAttributes:指向一个 SECURITY_ATTRIBUTES 结构的指针,用于指定事件对象的安全属性。如果传入 NULL,表示事件对象使用默认安全设置。
      • bManualReset:指定事件对象的重置方式。如果为 TRUE,表示事件对象是手动重置的,即调用 ResetEvent 函数才能将其状态重置为非 signaled;如果为 FALSE,表示事件对象是自动重置的,在一个等待线程被唤醒后,系统会自动将其状态重置为非 signaled。
      • bInitialState:指定事件对象的初始状态。如果为 TRUE,表示事件对象的初始状态为 signaled;如果为 FALSE,表示事件对象的初始状态为 nonsignaled。
      • lpName:事件对象的名称,可选参数。如果为 NULL,表示不指定名称。
    • 根据编译选项,CreateEvent 可以是 CreateEventA(ANSI 版本)或者 CreateEventW(Unicode 版本)。如果定义了 UNICODE 宏,则 CreateEvent 将被重定向到 CreateEventW,否则将被重定向到 CreateEventACreateEventW 使用宽字符(Unicode)作为参数,而 CreateEventA 使用 ANSI 字符作为参数。

    • 这种通过 #ifdef 宏定义来实现编译时切换函数的方式,是为了让程序能够兼容不同的字符集设置(Unicode 或 ANSI)。

	InitializeEvents();

	HANDLE hThread = CreateThread(NULL, 0, ThreadProcXinYou, (LPVOID)direct_url, 0, NULL);
	if (hThread == NULL) 
	{
		TRACEE("Failed to create thread for ShowXinYouIE.");
		return -1;
	}

	//SetEvent(g_hStopEvent);

	// 等待线程结束或超时
	if (WaitForSingleObject(hThread, 4000) == WAIT_TIMEOUT) 
	{
		TRACEE("ShowXinYouIE timed out.");
		//SetEvent(g_hStopEvent);  // 通知线程停止
		CXinYouLoginDlg::CloseXinYouIE(); // 超时关闭
	}
	else
	{
		CXinYouLoginDlg::CloseXinYouIE(); // 超时关闭
	}
	

	CloseHandle(hThread);
	CleanupEvents();
  • 这段代码主要用于创建一个线程来执行名为 ThreadProcXinYou 的线程函数,并在一定时间内等待线程结束或超时。然后根据等待的结果执行相应的操作。
    1. InitializeEvents():该函数用于初始化事件对象。
    2. HANDLE hThread = CreateThread(NULL, 0, ThreadProcXinYou, (LPVOID)direct_url, 0, NULL);:这行代码创建了一个新的线程,并将线程的句柄保存在 hThread 变量中。线程的入口点是 ThreadProcXinYou 函数,而 (LPVOID)direct_url 则是传递给线程函数的参数。
    3. if (hThread == NULL):这个条件判断语句检查线程是否成功创建。如果创建失败,会输出错误信息并返回错误码 -1
    4. if (WaitForSingleObject(hThread, 4000) == WAIT_TIMEOUT):这行代码等待线程结束或者等待超时。WaitForSingleObject 函数会等待指定的对象(这里是线程 hThread)进入 signaled 状态,或者等待超时。在这里,它等待线程结束,超时时间为 4000 毫秒(即 4 秒)。
    5. TRACEE("ShowXinYouIE timed out.");:如果等待超时,会输出一条错误信息。
    6. CXinYouLoginDlg::CloseXinYouIE();:在等待超时后,关闭了相关的资源,这里关闭了名为 CXinYouLoginDlg 的对象的 CloseXinYouIE 方法。
    7. else:如果线程在超时前结束了,执行这个分支。
    8. CloseHandle(hThread);:关闭线程句柄。
    9. CleanupEvents();:清理事件对象。
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateThread(
    __in_opt  LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in      SIZE_T dwStackSize,
    __in      LPTHREAD_START_ROUTINE lpStartAddress,
    __in_opt  LPVOID lpParameter,
    __in      DWORD dwCreationFlags,
    __out_opt LPDWORD lpThreadId
    );
  • 这是 Windows API 中的 CreateThread 函数的声明,它用于创建一个新的线程。
    • 参数解释如下:
      • lpThreadAttributes:指向 SECURITY_ATTRIBUTES 结构的指针,用于指定线程的安全属性。如果传入 NULL,表示线程使用默认安全设置。
      • dwStackSize:指定线程的堆栈大小。如果传入 0,则使用默认的堆栈大小(通常由操作系统决定)。
      • lpStartAddress:指定线程的入口点,即线程开始执行的函数。这个函数的签名必须与 LPTHREAD_START_ROUTINE 指定的一致。
      • lpParameter:传递给线程函数的参数。可以是任意类型的数据,通常是一个指针。
      • dwCreationFlags:用于指定额外的标志来控制线程的创建方式。例如,可以指定 CREATE_SUSPENDED 标志来创建一个挂起的线程,直到调用 ResumeThread 函数才开始执行。
      • lpThreadId:一个指向 DWORD 类型变量的指针,用于接收新创建线程的标识符。如果不需要此信息,可以传入 NULL
    • 该函数的返回值是新创建线程的句柄。如果创建失败,返回值为 NULL
    • 这个函数的作用是创建一个新的线程,并开始执行指定的线程函数(入口点)。
WINBASEAPI
DWORD
WINAPI
WaitForSingleObject(
    __in HANDLE hHandle,
    __in DWORD dwMilliseconds
    );
  • 这是 Windows API 中的 WaitForSingleObject 函数的声明。

    • 参数解释如下:

      • hHandle要等待的内核对象的句柄,可以是线程、进程、事件、互斥体、信号量等。
      • dwMilliseconds:等待的时间,以毫秒为单位。如果设置为 INFINITE,则表示无限期等待,直到对象变为 signaled 状态或者等待过程中发生错误。
    • 该函数的返回值指示等待对象的状态。可能的返回值包括:

      • WAIT_OBJECT_0:对象变为 signaled 状态,等待成功。
      • WAIT_TIMEOUT:超时,对象未变为 signaled 状态。
      • 其他错误代码:例如 WAIT_FAILED 表示等待失败,可以调用 GetLastError 函数获取更多信息。
  • 这个函数的作用是等待一个内核对象进入 signaled 状态。

	if (WaitForSingleObject(CSDOLApp::GetInstance()->GetStopEvent(), 0) == WAIT_OBJECT_0) 
	{
		delete pIe;  // 释放分配的对话框实例
		m_pXinYouIe = NULL; // 确保清理类成员变量
		return NULL;  // 提前返回
	}
  • 这段代码检查名为 g_hStopEvent 的事件对象是否处于 signaled 状态。WaitForSingleObject 函数会等待 g_hStopEvent 进入 signaled 状态,超时时间设置为 0,即立即返回。

    • 如果

      WaitForSingleObject
      

      返回

      WAIT_OBJECT_0
      

      ,表示事件对象处于 signaled 状态,即 判断g_hStopEvent事件的状态:

      g_hStopEvent
      

      已经被设置。在这种情况下,代码执行以下操作:

      • 删除对话框实例 pIe
      • 将类成员变量 m_pXinYouIe 设置为 NULL,确保清理。
      • 然后提前返回 NULL。
  • 这段代码的作用是在事件对象 g_hStopEvent 被设置时,提前结束函数并进行相应的清理工。

WINBASEAPI
BOOL
WINAPI
ResetEvent(
    __in HANDLE hEvent
    );

  • 这是 Windows API 中的 ResetEvent 函数的声明。
    • 参数解释如下:
      • hEvent:要重置的事件对象的句柄。
    • 函数的作用是将指定的事件对象重置为非 signaled 状态。换句话说,当调用 ResetEvent 函数后,事件对象将不再处于 signaled 状态,等待其进入 signaled 状态的线程将继续等待。
    • 函数返回 TRUE 表示成功,返回 FALSE 表示失败。
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森明帮大于黑虎帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值