深入解析waitforsingleobject

一、waitforsingleobject时间

waitforsingleobject是Windows API中一种同步机制,其作用是等待一个关键对象的信号,或者等待某个时间间隔,以等待被通知、满足条件或者时间到达等情况发生。在使用waitforsingleobject时,可以通过参数timeout来设置等待的时间。如果在timeout时间内对象被释放,则该函数会返回WAIT_OBJECT_0,如果timeout时间内对象仍未被释放,则返回WAIT_TIMEOUT。

waitforsingleobject函数有一个非常棒的特性,它可以将调用的线程挂起,直到对象变成可以用。如果将timeout值设为0,那么 waitforsingleobject将会对对象的状态进行查询,如果处于可用状态,该函数会立即返回;否则,该函数会将线程挂起到对象变为可用。

DWORD WaitForSingleObject(
  HANDLE hHandle, // 要等待的对象的句柄
  DWORD  dwMilliseconds // 等待的时间,以毫秒为单位。设置为INFINITE表示等待无限长的时间。
);

二、waitforsingleobject返回1

waitforsingleobject函数返回值1代表WAIT_FAILED,这意味着这次等待没有成功。其中一种可能的情况是传入了一个无效的句柄。此外,WAIT_FAILED可能是因为内部错误导致的,这种情况可能需要进一步的调查和排除。

为了帮助你提高代码的鲁棒性,可以将参数hHandle传入WAIT_OBJECT_0_INTERNAL,这样函数将会返回0,代表成功等待,或者返回WAIT_TIMEOUT。

#define WAIT_OBJECT_0_INTERNAL ((DWORD)0x00000001L)

HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
DWORD dwWaitResult = WaitForSingleObject(hEvent, INFINITE);
if (dwWaitResult == WAIT_FAILED) {
  // handle wait failed.
}

三、waitforsingleobject和sleep

waitforsingleobject和sleep都是Windows API中的同步机制,它们都可以用来等待一些事件的发生。但是,waitforsingleobject有一个非常明显的优点:它可以接收Windows内核对象的句柄作为参数。因此,在处理文件、进程、线程等资源时,waitforsingleobject至关重要。

相比之下,sleep函数一般用于“暂停”程序的执行,仅当你希望暂时停止程序时才应该使用。但是,如果需要等待某个资源释放,sleep函数则是不适宜的。

由于waitforsingleobject可以接收的对象较多,因此waitforsingleobject可以用于任何需要等待对象的应用程序中。

HANDLE hFile = CreateFile("test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
  WaitForSingleObject(hFile, INFINITE);
  //...
  CloseHandle(hFile);
}
else {
  // handle file creation failed.
}

四、waitforsingleobject的作用qt

在Qt中,waitforsingleobject可以用来等待信号的触发。QEventLoop借助waitforsingleobject等待任意时间间隔,直到接收到一个触发某个事件的信号。

void MyObject::someLongRunningFunction() {
  //...
  QEventLoop waitLoop;
  connect(this, &MyObject::someSignal, &waitLoop, &QEventLoop::quit);
  connect(this, &MyObject::someTimeoutSignal, &waitLoop, &QEventLoop::quit);
  QTimer::singleShot(5000, this, &MyObject::someTimeoutSignal);
  waitLoop.exec();
  //...
}

五、waitforsingleobject在switch中

在一些特定的编程场景中,很常见的一种操作是使用switch语句来处理不同的Windows消息。此时,waitforsingleobject函数可以用来等待UserModeConsoleInput事件或用户输入事件等。

借助waitforsingleobject来等待这些事件,可以减轻程序的负担,同时还能简化程序的结构。

DWORD ConsoleInputLoop() {
  while (true) {
    DWORD dwWaitResult = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), INFINITE);
        
    if (dwWaitResult == WAIT_OBJECT_0) {
      //process console input
          
      INPUT_RECORD irInBuf[128];
      DWORD dwNumRead;
      if (ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), irInBuf, 128, &dwNumRead)) {
        //...
      }
      else {
        break;
      }
    }
    
    // handle wait result
    switch (dwWaitResult) {
      case WAIT_OBJECT_0 + 1:
        //...
        break;
      case WAIT_OBJECT_0 + 2:
        //...
        break;
      case WAIT_OBJECT_0 + 3:
        //...
        break;
      default:
        break;
    }
  }
}

六、waitforsingleobject卡顿

正常情况下,waitforsingleobject应该是一个非常高效的API。但是,在某些情况下,waitforsingleobject会出现阻塞、死锁等问题。这种情况下通常是因为等待的对象没有被正确释放或其状态不正确而导致的。

为了避免waitforsingleobject的卡顿,可以尝试使用WaitForMultipleObjects,减少waitforsingleobject的调用次数,并确保在使用waitforsingleobject时对象的状态都是正确的。

HANDLE hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE hEvents[2] = {hEvent1, hEvent2};
WaitForMultipleObjects(2, hEvents, TRUE, INFINITE);
//...

结语

waitforsingleobject是Windows API中重要的同步机制之一,它可以用来等待关键对象的信号、资源的释放或其他指定的事件。waitforsingleobject的使用不仅可以提高程序的效率,还可以简化程序的结构和设计。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/242992.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 12:53
下一篇 2024-12-12 12:53

相关推荐

  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25

发表回复

登录后才能评论