boost::asio学习 - io_service的run,run_one,poll,poll_one的区别

本文深入解析了Windows I/O服务的工作流程,包括核心函数do_one的执行机制,以及run、run_one、poll和poll_one等函数的区别与实现方式。

在这几个函数里其实都是调用了do_one这个函数,而这个函数的作用就是从获取完成端口状态,所有定时器以及网络事件都是通过do_one来调度的,do_one的函数原型:

size_t do_one(bool block, boost::system::error_code& ec)


它的第一个参数说明了是否阻塞,在do_one代码中:

BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, block ? timeout : 0);




可以看到如果为false,将等待时间为0(即不阻塞)。

 

而run,run_one,及poll,poll_one的实现也相当简单,如下:

// Run the event loop until stopped or no more work.
size_t run(boost::system::error_code& ec)
{
  if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
  {
    stop();
    ec = boost::system::error_code();
    return 0;
  }

  call_stack<win_iocp_io_service>::context ctx(this);

  size_t n = 0;
  while (do_one(true, ec))
    if (n != (std::numeric_limits<size_t>::max)())
      ++n;
  return n;
}

// Run until stopped or one operation is performed.
size_t run_one(boost::system::error_code& ec)
{
  if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
  {
    stop();
    ec = boost::system::error_code();
    return 0;
  }

  call_stack<win_iocp_io_service>::context ctx(this);

  return do_one(true, ec);
}

// Poll for operations without blocking.
size_t poll(boost::system::error_code& ec)
{
  if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
  {
    stop();
    ec = boost::system::error_code();
    return 0;
  }

  call_stack<win_iocp_io_service>::context ctx(this);

  size_t n = 0;
  while (do_one(false, ec))
    if (n != (std::numeric_limits<size_t>::max)())
      ++n;
  return n;
}

// Poll for one operation without blocking.
size_t poll_one(boost::system::error_code& ec)
{
  if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
  {
    stop();
    ec = boost::system::error_code();
    return 0;
  }

  call_stack<win_iocp_io_service>::context ctx(this);

  return do_one(false, ec);
}


可以看到run其实就是一直循环执行do_one,并且是以阻塞方式进行的(参数为true),而run_one同样是以阻塞方式进行的,但只执行一次do_one;poll和run几乎完全相同,只是它是以非阻塞方式执行do_one(参数为false),poll_one是以非阻塞方式执行一次do_one。

 

原文链接:http://my.oschina.net/jackwgm/blog/6314

[root@dcvserver03 Sunshine]# mkdir build mkdir: cannot create directory ‘build’: File exists [root@dcvserver03 Sunshine]# cd build [root@dcvserver03 build]# cmake .. \ > -DCMAKE_BUILD_TYPE=Release \ > -DBOOST_ROOT=/usr/local \ > -DBOOST_LIBRARYDIR=/usr/local/lib \ > -DMINIUPNP_INCLUDE_DIR=/usr/local/include \ > -DMINIUPNP_LIBRARY=/usr/local/lib/libminiupnpc.a /root/py/Sunshine Sunshine Branch: master PROJECT_NAME: Sunshine PROJECT_VERSION: 0.0.0 PROJECT_VERSION_MAJOR: 0 PROJECT_VERSION_MINOR: 0 PROJECT_VERSION_PATCH: 0 CMAKE_PROJECT_VERSION: 0.0.0 CMAKE_PROJECT_VERSION_MAJOR: 0 CMAKE_PROJECT_VERSION_MINOR: 0 CMAKE_PROJECT_VERSION_PATCH: 0 PROJECT_YEAR: 1990 PROJECT_MONTH: 01 PROJECT_DAY: 01 CMake Warning (dev) at cmake/macros/common.cmake:27 (_find_package): Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT variables. Run "cmake --help-policy CMP0144" for policy details. Use the cmake_policy command to set the policy and suppress this warning. CMake variable BOOST_ROOT is set to: /usr/local For compatibility, find_package is ignoring the variable, but code in a .cmake module might still use it. Call Stack (most recent call first): cmake/dependencies/Boost_Sunshine.cmake:33 (find_package) cmake/dependencies/common.cmake:5 (include) CMakeLists.txt:61 (include) This warning is for project developers. Use -Wno-dev to suppress it. -- Could NOT find Boost (missing: Boost_DIR) -- Boost v1.89.0 package not found in the system. Falling back to FetchContent. -- Boost: Release build, static libraries, MPI OFF, Python OFF, testing OFF -- Boost: libraries included: filesystem;locale;log;program_options;system;asio;crc;format;process;property_tree -- Boost.Charconv: quadmath support ON -- Boost.Context: architecture x86_64, binary format elf, ABI sysv, assembler gas, suffix .S, implementation fcontext -- Found the following ICU libraries: -- data (required): /usr/lib64/libicudata.so -- i18n (required): /usr/lib64/libicui18n.so -- uc (required): /usr/lib64/libicuuc.so -- Found ICU: /usr/include (found suitable version "50.2", minimum required is "4.8.1") -- Boost.Locale: iconv ON, ICU ON, POSIX ON, std ON, winapi OFF -- Found the following ICU libraries: -- data (required): /usr/lib64/libicudata.so -- i18n (required): /usr/lib64/libicui18n.so -- uc (required): /usr/lib64/libicuuc.so -- Found ICU: /usr/include (found version "50.2") -- Boost.Thread: threading API is pthread -- Boost include dirs: $<BUILD_INTERFACE:/root/py/Sunshine/build/_deps/boost-src/libs/headers/include> -- Boost libraries: Boost::filesystem;Boost::locale;Boost::log;Boost::program_options;Boost::system;Boost::asio;Boost::crc;Boost::format;Boost::process;Boost::property_tree -- Looking for fcntl -- Looking for fcntl - found -- Looking for ioctl -- Looking for ioctl - found -- Looking for poll -- Looking for poll - found -- Looking for getaddrinfo -- Looking for getaddrinfo - found -- Looking for getnameinfo -- Looking for getnameinfo - found -- Looking for gethostbyname_r -- Looking for gethostbyname_r - found -- Looking for gethostbyaddr_r -- Looking for gethostbyaddr_r - found -- Looking for inet_pton -- Looking for inet_pton - found -- Looking for inet_ntop -- Looking for inet_ntop - found -- Performing Test HAS_MSGHDR_FLAGS -- Performing Test HAS_MSGHDR_FLAGS - Success -- Check size of socklen_t -- Check size of socklen_t - done -- Check size of QOS_FLOWID -- Check size of QOS_FLOWID - failed -- Check size of PQOS_FLOWID -- Check size of PQOS_FLOWID - failed -- nlohmann_json v3.11.x package not found in the system. Falling back to FetchContent. -- Using the multi-header code from /root/py/Sunshine/build/_deps/json-src/include/ CMake Warning at third-party/libdisplaydevice/src/CMakeLists.txt:14 (message): Linux is not supported yet. -- nlohmann_json v3.11.x package not found in the system. Falling back to FetchContent. -- Checking for module 'miniupnpc' -- No package 'miniupnpc' found CMake Error at /usr/local/share/cmake-3.28/Modules/FindPkgConfig.cmake:619 (message): The following required packages were not found: - miniupnpc Call Stack (most recent call first): /usr/local/share/cmake-3.28/Modules/FindPkgConfig.cmake:841 (_pkg_check_modules_internal) cmake/dependencies/common.cmake:26 (pkg_check_modules) CMakeLists.txt:61 (include) -- Configuring incomplete, errors occurred! [root@dcvserver03 build]# [root@dcvserver03 build]# make -j$(nproc) VERBOSE=1 # 显示详细编译日志 make: *** No targets specified and no makefile found. Stop. [root@dcvserver03 build]# sudo make install make: *** No rule to make target `install'. Stop. [root@dcvserver03 build]# [root@dcvserver03 build]#
最新发布
11-19
<think> 我们面对的问题是在CentOS 7.9 + RTX 6000环境下构建Sunshine时出现的多个CMake错误。根据之前的分析和解决方案,我们将逐步解决以下问题: 1. Boost库缺失(-- Could NOT find Boost (missing: Boost_DIR)) 2. miniupnpc包未找到(The following required packages were not found: miniupnpc) 3. 目录不存在或缺少CMakeLists.txt文件(如:third-party/moonlight-common-c/enet不存在,third-party/Simple-Web-Server和third-party/libdisplaydevice缺少CMakeLists.txt) 4. 执行make时提示"No targets specified and no makefile found" 解决思路: 1. 确保所有子模块被正确初始化(使用git submodule) 2. 安装或构建缺失的依赖(Boost和miniupnpc) 3. 修复CMake配置以正确查找依赖 4. 重新运行CMake生成Makefile,然后执行make 具体步骤: 步骤1:确保子模块初始化 由于错误提示中涉及third-party目录下的几个子模块(moonlight-common-c/enet, Simple-Web-Server, libdisplaydevice)不存在或缺少CMakeLists.txt,这通常是因为这些子模块没有正确初始化。我们需要重新初始化子模块。 步骤2:安装系统依赖 安装构建所需的开发工具和库,包括Boost、miniupnpc以及其他依赖。 步骤3:手动构建并安装miniupnpc(因为系统包可能不可用) 步骤4:设置CMake参数,明确指定Boost和miniupnpc的路径 步骤5:重新运行CMake和make 详细步骤: 1. 重新初始化子模块: ```bash cd /root/py/Sunshine # 进入Sunshine项目目录 git submodule update --init --recursive ``` 这将确保third-party下的所有子模块被正确检出。 2. 安装系统依赖: ```bash sudo yum install -y epel-release sudo yum install -y cmake3 gcc-c++ make openssl-devel libX11-devel libXrandr-devel libXinerama-devel libXcursor-devel mesa-libGL-devel libvdpau-devel systemd-devel libva-devel opus-devel libx264-devel x265-devel # 设置cmake3为默认(如果系统默认cmake版本过低) sudo alternatives --install /usr/bin/cmake cmake /usr/bin/cmake3 10 ``` 3. 安装Boost(如果系统Boost版本低于1.70,则需要手动安装): ```bash # 下载并安装Boost 1.82.0 wget https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz tar xf boost_1_82_0.tar.gz cd boost_1_82_0 ./bootstrap.sh --prefix=/usr/local sudo ./b2 install --with-system --with-thread --with-filesystem --with-locale --with-log --with-program_options --with-asio --with-crc --with-format --with-process --with-property_tree -j$(nproc) cd .. ``` 4. 安装miniupnpc: ```bash git clone https://github.com/miniupnp/miniupnp.git cd miniupnp/miniupnpc make sudo make install cd ../.. ``` 5. 创建构建目录并运行CMake(指定依赖路径): ```bash cd /root/py/Sunshine mkdir -p build cd build cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DBOOST_ROOT=/usr/local \ -DBOOST_LIBRARYDIR=/usr/local/lib \ -DMINIUPNP_INCLUDE_DIR=/usr/local/include \ -DMINIUPNP_LIBRARY=/usr/local/lib/libminiupnpc.a ``` 6. 编译并安装: ```bash make -j$(nproc) sudo make install ``` 注意:如果CMake仍然找不到miniupnpc,可以尝试在CMake命令中直接指定miniupnpc的库路径和头文件路径,如上所示。 如果上述步骤中,仍然出现子模块相关错误,请检查third-party目录下的子模块是否存在且包含CMakeLists.txt文件。如果仍然缺失,可以尝试手动克隆: ```bash cd /root/py/Sunshine/third-party # 对于moonlight-common-c git clone https://github.com/moonlight-stream/moonlight-common-c.git cd moonlight-common-c git submodule update --init --recursive # 确保其子模块(包括enet)也被初始化 cd .. # 对于Simple-Web-Server git clone https://gitlab.com/eidheim/Simple-Web-Server.git # 对于libdisplaydevice git clone https://github.com/mariusmotea/libdisplaydevice.git ``` 然后重新运行CMake。 通过以上步骤,应该能够解决依赖问题并成功构建。 如果遇到其他问题,请提供具体的错误信息以便进一步分析。 §§相关问题§§ 1. 如何验证Boost和miniupnpc是否正确安装? 2. 如何解决CMake中查找库的常见问题? 3. 如何为Sunshine项目启用NVIDIA NVENC编码? </think> 在 CentOS 7.9 环境下构建 Sunshine 项目时遇到 CMake 配置错误,主要问题集中在依赖缺失和项目结构异常。以下是系统化的解决方案: --- ### 一、核心问题诊断 根据错误日志分析: 1. **Boost 缺失**:`Could NOT find Boost (missing: Boost_DIR)` 2. **miniupnpc 缺失**:`The following required packages were not found: miniupnpc` 3. **子模块异常**: - `/root/py/Sunshine/third-party/moonlight-common-c/enet` 目录不存在 - `Simple-Web-Server` 和 `libdisplaydevice` 缺少 CMakeLists.txt 4. **Makefile 未生成**:因 CMake 配置失败导致 --- ### 二、完整解决方案 #### 步骤 1:修复子模块初始化 ```bash cd /root/py/Sunshine # 重新初始化子模块 git submodule update --init --recursive # 手动修复缺失的库 git clone https://github.com/moonlight-stream/moonlight-common-c.git third-party/moonlight-common-c git clone https://github.com/eidheim/Simple-Web-Server.git third-party/Simple-Web-Server ``` #### 步骤 2:安装系统依赖 ```bash sudo yum install -y epel-release sudo yum install -y cmake3 gcc-c++ make openssl-devel libX11-devel libXrandr-devel sudo ln -s /usr/bin/cmake3 /usr/bin/cmake # 链接 cmake3 为默认 # 安装 miniupnpc sudo yum install -y miniupnpc-devel ``` #### 步骤 3:手动安装 Boost 1.82+ ```bash wget https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz tar xf boost_1_82_0.tar.gz cd boost_1_82_0 ./bootstrap.sh --prefix=/usr/local sudo ./b2 install --with-system --with-thread -j$(nproc) export BOOST_ROOT=/usr/local # 设置环境变量 ``` #### 步骤 4:修正 CMake 配置 ```bash cd /root/py/Sunshine/build # 清除旧配置 rm -rf * # 重新配置(指定依赖路径) cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DBOOST_ROOT=/usr/local \ -DBOOST_LIBRARYDIR=/usr/local/lib \ -DMINIUPNP_INCLUDE_DIR=/usr/include/miniupnpc \ -DMINIUPNP_LIBRARY=/usr/lib64/libminiupnpc.so ``` #### 步骤 5:编译安装 ```bash make -j$(nproc) VERBOSE=1 # 显示详细日志 sudo make install ``` --- ### 三、关键问题解析 #### 1. Boost 定位问题 CMake 通过 `FindBoost.cmake` 模块查找 Boost,需明确指定路径: ```cmake # 在 CMakeLists.txt 中添加 set(BOOST_ROOT "/usr/local") set(BOOST_LIBRARY_DIR "/usr/local/lib") find_package(Boost 1.70 REQUIRED COMPONENTS system thread) ``` #### 2. 子模块异常处理 Sunshine 的 `CMakeLists.txt` 依赖子模块结构: ``` third-party/ ├── moonlight-common-c/ │ ├── enet/ # 必须存在 │ └── CMakeLists.txt └── Simple-Web-Server/ └── CMakeLists.txt # 必须存在 ``` 通过 `git submodule update --init` 确保完整克隆[^2]。 #### 3. Makefile 生成机制 CMake 工作流程为: ```mermaid graph LR A[CMakeLists.txt] --> B(CMake 配置) B --> C{生成} C --> D[Makefile] D --> E[make 编译] ``` 配置失败会导致 Makefile 缺失[^4]。 --- ### 四、验证安装 ```bash # 检查 Sunshine 版本 /usr/local/bin/sunshine --version # 预期输出 Sunshine 0.0.0 (Linux x86_64) ``` --- ### 五、RTX 6000 专用优化 在 `sunshine.conf` 中添加: ```ini [encoders] nvenc = true hevc = 1 quality = 4 # 最高质量 [streaming] min_threads = 8 # 匹配 GPU 流处理器 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值