网络编程(15)——服务器如何主动退出

十五、day15

服务器主动退出一直是服务器设计必须考虑的一个方向,旨在能通过捕获信号使服务器安全退出。我们可以通过asio提供的信号机制绑定回调函数即可实现优雅退出。

之前服务器的主函数如下

#include "CSession.h"
#include "CServer.h"int main()
{try {boost::asio::io_context ioc;CServer s(ioc, 10086);ioc.run();}catch (std::exception& e) {std::cerr << "Exception: " << e.what() << '\n';}boost::asio::io_context io_context;
}

有两种修改方式,第一种基于condition_variable和lock_quit;第二种基于asio库

1)第一种实现方式

#include "CSession.h"
#include "CServer.h"
#include <csignal>
#include <thread>
#include <mutex>bool bstop = false;
std::condition_variable cond_quit;
std::mutex mutex_quit;void sig_handler(int sig) {if (sig == SIGINT or sig == SIGTERM) {std::unique_lock<std::mutex> lock_quit(mutex_quit);bstop = true;cond_quit.notify_one();}
}int main()
{try {boost::asio::io_context ioc;std::thread net_work_thread([&ioc] { // 使用子线程运行网络服务CServer s(ioc, 10086);ioc.run();});// 主线程执行以下操作// 捕获信号,并执行信号对应的回调函数signal(SIGINT, sig_handler);signal(SIGTERM, sig_handler);// 循环会占用资源,为了防止占用资源我们选择挂起while (!bstop) {std::unique_lock<std::mutex> lock_quit(mutex_quit);cond_quit.wait(lock_quit);}ioc.stop();net_work_thread.join();}catch (std::exception& e) {std::cerr << "Exception: " << e.what() << '\n';}boost::asio::io_context io_context;
}
  • 条件变量、关服标志、锁必须都是全局变量

  • 自定义关服回调函数sig_handler一旦捕获到SIGINT(Ctrl+C触发)或SIGTERM(终止进程信号),系统调用sig_handler函数。在回调函数内首先进行加锁,以免重复操作,然后将关服标志位置为true,并将主线程唤醒,'}'结束后自动解锁

  • 启动子线程运行网络服务

  • 主线程种设置信号处理函数并将主线程挂起,等待退出信号(循环会占用cpu资源,这里通过挂起避免循环,节省资源)

  • 当主线程被唤醒后,退出循环,执行ioc.stop()来停止io_context,并将子线程中的ioc.run()返回

  • net_work_thread.join()确保子线程在主线程退出之前先结束运行,防止资源泄露

注:信号处理是异步的,即使主线程在等待条件变量,也可以被信号打断,执行信号处理函数

2)第二种实现方式

int main()
{try {boost::asio::io_context ioc;boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);// 必须异步等待,否则建立线程进行处理signals.async_wait([&ioc](auto, auto) {ioc.stop();});CServer s(ioc, 10086);ioc.run();}catch (std::exception& e) {std::cerr << "Exception: " << e.what() << '\n';}boost::asio::io_context io_context;
}

第二种方式是我推荐的,最优雅最简单。

主要通过asio库的signal_set 函数执行信号处理操作,允许用户在指定的io_context 上异步等待这些信号的到来,并在信号到达时执行相应的回调

  • 异步处理: 通过将信号处理与 io_context 结合,程序能够继续处理其他异步任务,而不需要在信号到达时阻塞主线程。

  • 多线程支持: 如果程序使用多线程,信号的处理仍然可以有效地协调各个线程的操作。

3)测试

两种方式均能得到以下测试结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NetCore---I18n(internationalization)多语言版本的应用

文章目录 0.实现的效果如下1.创建新项目I18nBaseDemo2.添加页面中的下拉框3.在HomeController中添加ChangeLanguage方法4.在Progress.cs 文件中添加如下代码&#xff1a;5. 在progress.cs中添加code6.添加Resource资源文件7.在页面中引用i18n的变量8. 重启项目&#xff0c;应该…

力扣4. 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&#xff1a;2.00000 解释&…

神经网络激活函数汇总

神经网络中的激活函数用于引入非线性&#xff0c;使模型能够学习和表示复杂的模式。不同的激活函数有各自的特性和用途。常见的激活函数包括以下几种&#xff1a; 1. Sigmoid&#xff08;S型函数&#xff09; 公式&#xff1a; σ ( x ) 1 1 e − x \sigma(x) \frac{1}{1…

录屏达人必备!四款神器助你轻松搞定一切

录屏&#xff0c;一个既简单又实用的技能&#xff0c;不仅能帮助我们记录下电脑上的精彩瞬间&#xff0c;还能在需要的时候进行演示。是不是觉得特别棒呢&#xff1f;今天&#xff0c;我就来给大家分享一下如何轻松地录屏&#xff0c;并推荐四款非常实用的录屏工具。 一、如何录…

暴力目前98%-----找数字

题目描述 给一个二维数组nums&#xff0c;对于每一个元素nums[i]&#xff0c;找出距离最近的且值相等的元素&#xff0c; 输出横纵坐标差值的绝对值之和&#xff0c;如果没有等值元素&#xff0c;则输出-1。 例如&#xff1a; 输入数组 nums 为 0 3 5 4 2 2 5 7 8 3 2 5 4 …

力扣hot100--链表

链表 1. 2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff…

网络学习第二篇

认识网关和路由器 这里大家先了解一下什么三层设备。 三层设备 三层设备是指在网络架构中能够工作在第三层&#xff08;网络层&#xff09;的设备&#xff0c;通常包括三层交换机和路由器。这些设备可以根据IP地址进行数据包的转发和路由选择&#xff0c;从而在不同的网络之间…

JVM Class类文件结构

国庆节快乐 2024年10月2日17:49:22 目录 前言 magic 数 文件版本 使用JClassLib观察class文件 一般信息 接口 常量池 字段 方法 常量池计数器 常量池 类型 CONSTANT_Methodref_info CONSTANT_Class_info 类型结构总表 访问标志 类索引, …

【DataSophon】DataSophon1.2.1 整合Zeppelin并配置Hive|Trino|Spark解释器

目录 ​一、Zeppelin简介 二、实现步骤 2.1 Zeppelin包下载 2.2 work配置文件 三、配置常用解释器 3.1配置Hive解释器 3.2 配置trino解释器 3.3 配置Spark解释器 一、Zeppelin简介 Zeppelin是Apache基金会下的一个开源框架&#xff0c;它提供了一个数据可视化的框架&am…

【秋招笔试】10.08华为荣耀秋招(已改编)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 本次的三题全部上线…

每天一道面试题5——Linux内核包含哪些部分?

Linux 内核的组成部分&#xff1a; 进程管理&#xff08;Process Management&#xff09; 功能&#xff1a;负责管理系统中的所有进程&#xff0c;包括进程的创建、调度、终止&#xff0c;以及多任务处理。进程管理还处理线程和进程的并发与同步问题。调度器&#xff1a;Linux …

影视cms泛目录用什么程序?苹果cms二次开发泛目录插件

影视CMS泛目录一般使用的程序有很多种&#xff0c;&#xff08;maccmscn&#xff09;以下是其中几种常见的程序&#xff1a; WordPress&#xff1a;WordPress是一个非常流行的开源内容管理系统&#xff0c;可以通过安装一些插件来实现影视CMS泛目录功能。其中&#xff0c;一款常…

基于H3C环境的实验——OSPF

目录 实验设备和环境 实验设备 实验环境 实验记录 1、单区域 OSPF基本配置 步骤1:搭建实验环境并完成基本配置 步骤2:检查网络连通性和路由器路由表。 步骤3:配置OSPF 步骤4:检查路由器OSPF邻居状态及路由表 实验设备和环境 实验设备 三台路由器、两台PC、电源线、两…

Kubernetes中部署ELK Stack日志收集平台

1 、ELK概念 ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中: Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elas…

【Spring】@RequestMapping、@RestController和Postman

文章目录 1.RequestMapping 注解介绍2. RequestMapping 使用3. RequestMapping 是 GET 还是 POST 请求&#xff1f;GET 请求POST 请求指定 GET/POST 方法类型 2. Postman 介绍1. 创建请求2. 传参介绍1. 普通传参2. form-data3. x-www-form-urlencoded4. raw 1.RequestMapping 注…

微积分复习笔记 Calculus Volume 1 - 2.2 The Limit of a Function

2.2 The Limit of a Function - Calculus Volume 1 | OpenStax

stateflow一些数据依赖关系的使用

https://www.youtube.com/watch?vNW03ZAQcTuY 某些数据来自其他数据&#xff0c;可以用flow进行一些变形转换 比较简单一点的例子 private val _users MutableStateFlow(emptyList<User>())val users _users.asStateFlow()// private val _loacalUser MutableSta…

MES 制造执行系统的国内外应用现状及国内应用案例

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在当今制造业数字化转型的浪潮中&#xff0c;制造执行系统&#xff08;MES&#xff09;发挥着至关重要的作用。国内外的企业在 MES 系统的应用方面呈现出不同的特…

【记录】PPT|PPT 箭头相交怎么跨过

众所周知&#xff0c;在PPT中实现“跨线”效果并非直接可行&#xff0c;这一功能仅存在于Visio中。然而&#xff0c;通过一些巧妙的方法&#xff0c;我们可以在PPT中模拟出类似的效果。怎么在PPT中画交叉但不重叠的线-百度经验中介绍了一种方法&#xff0c;而本文将介绍一种改进…

Stable Diffusion绘画 | 签名、字体、Logo设计

第1步&#xff0c;使用 PS&#xff08;小白推荐使用 可画&#xff09;准备一个 512*768 的签名、字体、Logo图片&#xff1a; 第2步&#xff0c;来到模型网站&#xff0c;搜索&#x1f50d;关键词“电商”&#xff0c;找到一款喜欢的 LoRA&#xff1a; 第3步&#xff0c;选择一…