【C++boost::asio网络编程】有关服务端退出方法的笔记

embedded/2024/12/28 3:57:26/

有关服务端退出方法的笔记

  • C风格的信号关闭
  • boost::asio中的关闭方式

原来服务端的main函数如下

int main()
{try{boost::asio::io_context ioc;Server s(ioc, 8888);ioc.run();}catch (const std::exception&){}return 0;
}

  上面弊端在于缺乏好的退出机制,目前,ioc.run() 会一直阻塞,直到 io_context 被显式地停止。然而,如果没有显式的退出信号或退出条件(如 SIGINT、SIGTERM 信号等),程序将无法优雅地退出。万一在运行时出现异常,或者程序需要在特定时机停止时,缺乏退出机制可能导致程序无法正常关闭。
  如果服务器程序无法响应中断信号或其他退出信号,可能会影响系统资源的释放,造成资源泄漏(如打开的网络连接、文件句柄等)。

C风格的信号关闭

#include <boost/asio.hpp>
#include <iostream>
#include "Session.h"
#include <thread>
#include <mutex>
#include <csignal>bool bstop = false;
std::condition_variable cond_quit;
std::mutex mutex_quit;void sig_handle(int sig)
{if (sig == SIGINT || sig == SIGTERM){std::unique_lock<std::mutex> lock(mutex_quit);bstop = true;cond_quit.notify_one();}
}int main()
{try{boost::asio::io_context ioc;std::thread net_work([&ioc] {Server s(ioc, 8888);ioc.run();});signal(SIGINT, sig_handle);signal(SIGTERM, sig_handle);while (!bstop){std::unique_lock<std::mutex> lock(mutex_quit);cond_quit.wait(lock);}ioc.stop();net_work.join();}catch (const std::exception&){}return 0;
}

  这里可以看到,不同于之前的主线程来进行轮询、收发数据的处理,这里采用了使用一个新线程net_work来负责原先主线程的任务,然后主线程负责监听SIGINTSIGTERM两个信号
  当程序正在运行的时候,如果想要终止程序,我们就可以通过向该进程发送信号来执行终止逻辑sig_handle。下面简单介绍一下主线程在干什么

signal(SIGINT, sig_handle);
signal(SIGTERM, sig_handle);
while (!bstop)
{std::unique_lock<std::mutex> lock(mutex_quit);cond_quit.wait(lock);
}
ioc.stop();
net_work.join();

  在while循环内部,定义了一个std::unique_lock<std::mutex>类型的变量,这个unique_lock主要就是和条件变量condition_variable 来搭配使用的。当发现当发现bstop(用来判断当前进程是否需要终止)为假时,进行循环,然后让主线程在条件变量下等待
可以不设置条件变量一直死循环吗?
  这么做虽然逻辑上可以,但是一直死循环会导致当前线程一直占用CPU资源造成资源浪费的现象,比较好的处理方案就是让该线程进入阻塞状态。然后我们给改进程发送信号时,执行sig_handle函数

void sig_handle(int sig)
{if (sig == SIGINT || sig == SIGTERM){std::unique_lock<std::mutex> lock(mutex_quit);bstop = true;cond_quit.notify_one();}
}

  在这个函数中,会将bstop设置为true,表示整个程序应该要终止了,然后去唤醒主线程告诉它要去进行收尾的逻辑

ioc.stop();
net_work.join();

  回到主线程,退出循环之后,停止掉ioc,然后去等待回收net_work线程,回收之后再退出,此时整个程序也就安全退出了

boost::asio中的关闭方式

int main()
{try{boost::asio::io_context ioc;boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&ioc](auto, auto) {ioc.stop();});Server s(ioc, 8888);ioc.run();}catch (const std::exception&){}return 0;
}
boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);

  这一行创建了一个 boost::asio::signal_set 对象signals。signal_set 用于注册对特定信号(如中断信号 SIGINT 或终止信号 SIGTERM)的异步处理。这里注册了 SIGINT(通常是按下 Ctrl+C 时触发)和 SIGTERM(终止进程的信号)信号。
  signals 会监听这些信号,并触发相关的回调函数。

signals.async_wait([&ioc](auto, auto) { ioc.stop(); });

  这行代码使用了 async_wait 来等待信号的异步触发。回调函数会在 SIGINT 或 SIGTERM 信号到达时被调用。在回调函数内部,调用了 ioc.stop(),这会停止 io_context 的事件循环。当信号到达时,ioc.stop() 会中断事件循环的运行,允许程序优雅地退出


http://www.ppmy.cn/embedded/149352.html

相关文章

Android okhttp 网络链接各阶段监控

步骤 1: 添加依赖 在项目的 build.gradle 文件中&#xff0c;添加 OkHttp 依赖&#xff1a; implementation com.squareup.okhttp3:okhttp:4.11.0 步骤 2: 创建自定义的 EventListener 创建一个自定义的 EventListener 类&#xff1a; import android.util.Log import okht…

【漏洞复现】灵当CRM datapdf.php 任意文件读取漏洞

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…

Kafka、RocketMQ、RabbitMQ 对比

面试中对 Kafka 、 RocketMQ 、和 RabbitMQ 的对比是常见问题&#xff0c;可以从以下几个维度进行分析&#xff1a; 1️⃣ 基础概念 特性KafkaRocketMQRabbitMQ开发语言Java ScalaJavaErlang定位分布式流处理平台分布式消息中间件高效、可靠的消息队列消息模型Topic &#xf…

信息抽取(NLP)是什么技术有哪些应用?

信息抽取是将非结构化的信息转化为结构化信息的过程。一般应用于电商平均分析、知识图谱和大模型训练。 不同模型的对比 1. 规则模型 优点 简单直观:基于人工设定的规则,不需要大量的数据集进行训练,只要规则制定者对目标信息有清晰的理解即可开始构建。例如,对于一些具有…

taro中实现带有途径点的路径规划

前言 taro中实现带有途径点的路径规划 import React, {useState, useEffect} from "react"; import {View, Map, ScrollView} from tarojs/components import Taro, {useRouter} from tarojs/taro; import request from ../../request; import api from ../../reque…

Spring Boot 中 Map 的最佳实践

在Spring Boot中使用Map时&#xff0c;请遵循以下最佳实践: 1.避免在Controller中 直接使用Map。应该使用RequestBody 接收-个DTO对象或者 RequestParam接收参数&#xff0c;然后在Service中处 理Map。 2.避免在Service中 直接使用原始的Map。应该使用Autowired 注入-个专门…

elementUI——upload限制图片或者文件只能上传一个——公开版

最近在写后台管理系统时&#xff0c;遇到一个需求&#xff0c;就是上传图片&#xff0c;有且仅能上传一张。 效果图如下&#xff1a; 功能描述&#xff1a;上传图片时&#xff0c;仅支持单选&#xff0c;如果上传图片成功后&#xff0c;展示图片&#xff0c;并隐藏添加图片的…

Linux shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件

Linux Debian12基于ImageMagick图像处理工具编写shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件&#xff0c;”多个图片分开生成多个PDF文件“或者“多个图片合并生成一个PDF文件” BiliBili视频链接&#xff1a; Linux shell脚本对常见图片格式批量转换…