• 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以异步方式将字符串写入标准输出流。

  • 相关阅读:
    Jenkins 中 shell 脚本执行失败却不自行退出
    虾皮印尼买家号如何注册
    跟我学Python图像处理丨基于灰度三维图的图像顶帽运算和黑帽运算
    数据结构与算法训练:第十三弹
    高频笔试题(蔚来)
    GPT访问跨域如何解决呢?
    非零基础自学Java (老师:韩顺平) 第14章 集合 14.9 Set 接口和常用方法
    计算/存储虚拟化高级特性
    Spring Cloud Feign实战
    如何提高加速运行Mac电脑系统缓慢的5种方法教程
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/126596880