• Boost ASIO:Platform-specific I/O Objects


    Abstract

    Asio还提供了特定于平台的I/O对象,因为有些异步操作只在某些平台上可用,例如Windows或Linux。

    How

    目录监控

    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace boost::asio;
    using namespace boost::system;
    
    int main()
    {
      io_service ioservice;
    
      HANDLE file_handle = CreateFileA(".", FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
    
      char buffer[1024];
      DWORD transferred;
      OVERLAPPED overlapped;
      ZeroMemory(&overlapped, sizeof(overlapped));
      overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
      ReadDirectoryChangesW(file_handle, buffer, sizeof(buffer), FALSE,
        FILE_NOTIFY_CHANGE_FILE_NAME, &transferred, &overlapped, NULL);
    
      windows::object_handle obj_handle{ioservice, overlapped.hEvent};
      obj_handle.async_wait([&buffer, &overlapped](const error_code &ec) {
        if (!ec)
        {
          DWORD transferred;
          GetOverlappedResult(overlapped.hEvent, &overlapped, &transferred,
            FALSE);
          auto notification = reinterpret_cast(buffer);
          std::wcout << notification->Action << '\n';
          std::streamsize size = notification->FileNameLength / sizeof(wchar_t);
          std::wcout.write(notification->FileName, size);
        }
      });
    
      ioservice.run();
    }

    这个例子中使用了I/O对象boost::asio::windows::object_handle,该对象仅在windows上可用。boost::asio::windows::object_handle,它基于windows函数RegisterWaitForSingleObject(),让你启动对象句柄的异步操作。RegisterWaitForSingleObject()接受的所有句柄都可以通过boost::asio::windows::object_handle使用。使用async_wait(),可以异步等待对象句柄的更改。

    初始化boost::asio::windows::object_handle类型的对象obj_handle,使用windows函数CreateEvent()创建的对象句柄。句柄是OVERLAPPED结构的一部分,其地址传递给Windows函数ReadDirectoryChangesW()。Windows使用OVERLAPPED结构来启动异步操作。

    ReadDirectoryChangesW()可用于监视目录并等待更改。要异步调用该函数,必须将OVERLAPPED结构传递给ReadDirectoryChangesW()。通过Boost报告异步操作的完成情况。Asio,事件处理程序在传递给ReadDirectoryChangesW()之前存储在OVERLAPPED结构中。这个事件处理程序随后被传递给obj_handle。当在obj_handle上调用async_wait()时,当在观察到的目录中检测到更改时,将执行处理程序。

    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace boost::asio;
    using namespace boost::system;
    
    int main()
    {
      io_service ioservice;
    
      HANDLE file_handle = CreateFileA(".", FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
    
      error_code ec;
      auto &io_service_impl = use_service(ioservice);
      io_service_impl.register_handle(file_handle, ec);
    
      char buffer[1024];
      auto handler = [&buffer](const error_code &ec, std::size_t) {
        if (!ec)
        {
          auto notification =
            reinterpret_cast(buffer);
          std::wcout << notification->Action << '\n';
          std::streamsize size = notification->FileNameLength / sizeof(wchar_t);
          std::wcout.write(notification->FileName, size);
        }
      };
      windows::overlapped_ptr overlapped{ioservice, handler};
      DWORD transferred;
      BOOL ok = ReadDirectoryChangesW(file_handle, buffer, sizeof(buffer),
        FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &transferred, overlapped.get(),
        NULL);
      int last_error = GetLastError();
      if (!ok && last_error != ERROR_IO_PENDING)
      {
        error_code ec{last_error, error::get_system_category()};
        overlapped.complete(ec, 0);
      }
      else
      {
        overlapped.release();
      }
    
      ioservice.run();
    }

    boost::asio::windows::overlapped_ptr是一个I/O对象,它没有启动异步操作的成员函数。异步操作是通过将内部OVERLAPPED变量的指针传递给一个Windows函数开始的。除了一个I/O服务对象之外,boost::asio::windows::overlapped_ptr的构造函数还期望在异步操作完成时调用一个处理程序。

    异步写文件

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace boost::asio;
    
    int main()
    {
      io_service ioservice;
    
      posix::stream_descriptor stream{ioservice, STDOUT_FILENO};
      auto handler = [](const boost::system::error_code&, std::size_t) {
        std::cout << ", world!\n";
      };
      async_write(stream, buffer("Hello"), handler);
    
      ioservice.run();
    }

    boost::asio::posix::stream_descriptor can be initialized with a file descriptor to start an asynchronous operation on that file descriptor. In the example, stream is linked to the file descriptor STDOUT_FILENO to write a string asynchronously to the standard output stream.

    Boost::asio::posix::stream_descriptor可以用一个文件描述符初始化,以启动对该文件描述符的异步操作。在示例中,流链接到文件描述符STDOUT_FILENO以异步方式将字符串写入标准输出流。

  • 相关阅读:
    PostgreSQL的学习心得和知识总结(一百四十八)|查看 PostgreSQL 17 中的新内置排序规则提供程序
    vue-在组件中使用v-model
    openGauss学习笔记-90 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用重试中止事务
    建模仿真软件 Comsol Multiphysics mac中文版软件介绍
    [激光原理与应用-25]:《激光原理与技术》-11- 控制技术-非线性技术之激光倍频、非线性晶体CLBO、BBO、LBO
    IntelliJ IDEA 2023.2新特性详解第二弹!
    web3 前端dapp从redux过滤出 (我创建与别人创建)正在执行的订单 并展示在Table上
    使用 VuePress 和 Vercel 打造个人技术博客:实现自动化部署
    norflash 中块和扇区的关系
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java散酒营销系统w5at6
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/126596880