Windows创建线程与事件示例

文章目录

  • 1、# 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 被设置时,提前结束函数并进行相应的清理工

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web 前端 Javascript笔记2

1、数组 为什么需要数组:因为变量只能存储一条数据,但是储存多条数据 数组的声明方式 1、new let a1new Array() console.log(a1) 2、字面量 let a2[1,2,4,"k",true,"zhangsan",11] console.log(a2) 数组里面可以存放不同的数据类…

【Vue】v-model和.sync

Vue中的v-model和.sync修饰符都是用于实现父子组件间数据双向绑定的机制。尽管它们的作用相似,但在使用方式和实现细节上有所区别。 v-model v-model是一个指令,用于在表单类元素上创建双向数据绑定。在Vue3中,v-model可以在自定义组件上使用…

深入理解go语言中的切片

写在文章开头 从一个Java的开发角度来看,切片我们可以理解为Java中的ArrayList即一种动态数组的实现,本文会从源码的角度对切片进行深入剖析,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java …

loadash常用的函数方法

Lodash是一个JavaScript实用工具库,提供了很多常用的函数方法来简化开发过程。以下是一些常用的Lodash函数方法: _.map(array, iteratee):对数组中的每个元素应用一个函数,并返回结果数组。_.filter(collection, predicate)&…

Transformer架构实现一

从0-1搭建Transformer架构 架构图 本文主要讲解 1)输入层的词嵌入 2)输入层的位置编码 3)编码层的多头注意力机制 4)编码层的前馈全连接 1)输入层的词嵌入 class Embeddings(nn.Module):"""构建emb…

a == 1 a== 2 a== 3 返回 true ?

1. 前言 下面这道题是 阿里、百度、腾讯 三个大厂都出过的面试题,一个前端同事跳槽面试也被问了这道题 // ? 位置应该怎么写,才能输出 trueconst a ?console.log(a 1 && a 2 && a 3) 看了大厂的面试题会对面试官的精神…

git操作基本命令

Git命令操作: 1、服务器上面有新的修改,pull出现错误操作如下 git stash git pull origin master git stash pop 2、删除本地一个文件test.py,想重新download远程服务器最新的文件 #git checkout test.py 3、查看当前处于哪一个分支 #git …

代码随想录算法训练营第五十天|123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。 视频讲解:https://www.bilibili.com/video/BV1WG411K7AR https://programmercarl.com…

数码相框-显示JPG图片

LCD控制器会将LCD上的屏幕数据映射在相应的显存位置上。 通过libjpeg把jpg图片解压出来RGB原始数据。 libjpeg是使用c语言实现的读写jpeg文件的库。 使用libjpeg的应用程序是以"scanline"为单位进行图像处理的。 libjpeg解压图片的步骤: libjpeg的使…

maven 项目示例

maven 项目 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><properti…

【御控物联】物联网平台设备接入-JSON数据格式转化(场景案例四)

文章目录 一、背景二、解决方案三、在线转换工具四、技术资料 一、背景 物联网平台是一种实现设备接入、设备监控、设备管理、数据存储、消息多源转发和数据分析等能力的一体化平台。南向支持连接海量异构&#xff08;协议多样&#xff09;设备&#xff0c;实现设备数据云端存…

第6章 6.2 :文本数据的导入和导出操作(MATLAB入门课程)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 在数据处理和分析中&#xff0c;文本数据的导入和导出操作&…

前端开发攻略---在输入框中输入中文但是还没选中的时候,搜索事件依然存在;中文输入法导致的高频事件。

1、演示 解决前 解决后 2、输入框事件介绍 compositionstart事件在用户开始使用输入法输入时触发。这意味着用户正在进行组合输入&#xff0c;比如在中文输入法中&#xff0c;用户可能正在输入一个多个字符的词语。在这个阶段&#xff0c;输入框的内容可能还没有完全确定&#…

RocketMQ 10 面试题FAQ

RocketMQ 面试FAQ 说说你们公司线上生产环境用的是什么消息中间件? 为什么要使用MQ&#xff1f; 因为项目比较大&#xff0c;做了分布式系统&#xff0c;所有远程服务调用请求都是同步执行经常出问题&#xff0c;所以引入了mq 解耦 系统耦合度降低&#xff0c;没有强依赖…

Testng测试框架(2)-测试用例@Test

测试方法用 Test 进行注释&#xff0c;将类或方法标记为测试的一部分。 Test() public void aFastTest() {System.out.println("Fast test"); }import org.testng.annotations.Test;public class TestExample {Test(description "测试用例1")public void…

Android JNI 在C++多线程调用Java的回调函数

java 接口定义&#xff1a; public interface Callback {void onResult(int status, String message); } java 设置回调&#xff1a; public class Sample {static {System.loadLibrary("sample_core_jni");}public static native int process(long handle, Strin…

chown命令用法示例

chown 是一个 Linux/Unix 命令&#xff0c;用于改变文件或目录的所有者。通常情况下&#xff0c;只有超级用户&#xff08;root&#xff09;或文件的所有者才能使用 chown 命令。 基本的 chown 语法如下&#xff1a; chown [新的所有者]:[新的组] 文件或目录[新的所有者]&…

如何通过Python向PDF添加文本水印_python给pdf文件加文字水印

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

频率传感器信号采集隔离转换模拟信号0-1KHz/0-5KHz/0-10KH转0-2.5V/0-5V/0-10V/0-10mA/0-20mA/4-20mA

主要特性: >> 精度等级&#xff1a;0.2 级 >> 全量程内极高的线性度&#xff08;非线性度<0.1%&#xff09; >> 辅助电源/信号输入/信号输出&#xff1a; 2500VDC 三隔离 >> 辅助电源&#xff1a;5VDC&#xff0c;12VDC&#xff0c;24VDC 等单…

Redis Desktop Manager 中文--强大的Redis数据库管理工具

Redis Desktop Manager&#xff08;简称RDM&#xff09;是一款开源且功能强大的图形化Redis管理工具。它支持Windows、macOS和Linux等多平台&#xff0c;为Redis数据库提供了直观友好的管理界面。通过RDM&#xff0c;用户可以轻松连接多个Redis服务器&#xff0c;管理连接信息&…