udp/tcp错误总结

devtools/2024/9/23 7:33:28/

udp
tcp——多进程
tcp——多线程
tcp——线程池
tcp——守护进程

🎆udp
 ✨pthread_create 错误总结
 ✨LockGuard错误总结
 ✨服务端需要写成多线程
 ✨客户端也需要写成多线程
 ✨多线程调试工具
🎆tcp
 ✨tcp独有调试工具——telnet
 ✨ThreadPool —— 短连接
 ✨pthread_create —— 长连接
 ✨fork——长连接
 ✨进程池版的守护进程

在这里插入图片描述

🎆udp

✨1. pthread_create 错误总结

    static void* Routine(void* argv){// 线程本身就是运行起来一次就要结束,结束的动作由外部执行Thread* th = static_cast<Thread*>(argv);th->_fun(th->_info);// 线程自动调用这个函数,并将参数传递过去return nullptr;}bool Start(){cout << _name ;puts(" 线程将要运行");int n = pthread_create(&_tid,nullptr,Routine,this);cout << _name;puts(" 线程已经运行");if(n)return false;return true;}

pthread_create 不能使用 bind 进行绑定,只能使用static 函数进行创建

✨2. LockGuard错误总结

class LockGuard
{
public:// 锁必须传指针,不能传值/引用// 传值/引用会造成死锁现象LockGuard(const std::string& func_name, pthread_mutex_t* mtx):_func_name(func_name),_mutex(mtx){// puts("上锁");std::cout << "LockGuard:" <<  _func_name << "上锁" << std::endl;pthread_mutex_lock(_mutex);// 死锁位置// puts("上锁完成");std::cout << "LockGuard:" <<  _func_name << "上锁完成" << std::endl;}~LockGuard(){// puts("开始解锁");std::cout << "LockGuard:" << _func_name << "解锁" << std::endl;pthread_mutex_unlock(_mutex);// puts("解锁完成");}
private:// pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;// 这个锁不能初始化,这个锁用的是外面的锁pthread_mutex_t* _mutex;std::string _func_name;
};

​ 必须使用传指针的方式,如果使用传引用/传值的方式,就会出现死锁

✨3. 服务端需要写成多线程

如果写成单线程,可能会出现服务端只为一个服务,另一个发送消息显示不出来的情况;当此连接释放才能将内容显示出来

✨4. 客户端也需要写成多线程

需要一个send线程,一个recv线程
如果只有一个线程,线程如果阻塞在send线程,也就是需要从标准输入中读取才能进行发送,那么就无法进行recv;由于
udp有自己的缓冲区,所以即使无法运行recv也是可以将少量消息进行记录

✨5. 多线程调试工具

pstack —— 查看多进程函数栈
gdb attach 线程id
info threads——查看线程信息
t 线程编号——切换线程
info b——查看线程信息

详细请参考 多进程调试工具

🎆tcp

✨tcp独有调试工具——telnet

没有写客户端的情况下还想进行调试,可以使用telnet进行调试,telnet只能对tcp进行使用

ThreadPool —— 短连接

  1. 什么是短连接
    长连接:将一个接收和发送作为一个任务,一个线程一直做这一个工作,知道客户端关闭,线程结束
    短连接:将一个接收和发送作为一个任务,一个套接字执行一个任务之后立即释放

  2. 理解为什么TheadPool 模型必须使用短连接
    线程池中线程个数有限如果使用长连接,服务端只能接收有限的用户,很显然是不合理的

  3. 使用function包装函数类型不同头文件中可能出现函数类型重名的问题
    在这里插入图片描述

  4. 灵活规定ThreadPool的任务类型
    在这里插入图片描述
    问题一为什么ThreadPool的类型是Task,为什么不能是一个套接字或者别的
    首先我们要明确线程要执行的任务是:使用套接字进行接收+发送消息
    问题二accept 函数是在主线程or子线程
    肯定是在主线程中,如果在子线程中还需要考虑访问套接字冲突的问题
    所以传递套接字应该是传递的接收消息的套接字
    问题三:为什么要将执行函数封装进去,可不可以在Task类中进行执行
    在Task类中实现执行函数完全是OK的,最关键的一点是要在Task类中重载(),这样在使用的时候就可以像执行函数一样执行了
    在这里插入图片描述

注意:在子线程中,执行完一个任务需要将这个任务的接收消息的套接字关闭,防止资源消耗完
在这里插入图片描述

pthread_create —— 长连接

  1. 一定要明确变量是要被外部使用还是只在本作用域中使用
    在这里插入图片描述
    如果局部变量需要传给外部进行使用,并且接收的参数是指针,当外部进行使用的时候,当前空间已经被回收,就无法拿到原来的数据
    解决方法:
    方法一:将接收参数改为传值接收
    方法二传递堆空间
  2. 创建子线程需要进行分离每个子线程使用的是不同的描述套接字,所以不存在访问冲突的问题,不需要加锁
    在这里插入图片描述

fork——长连接

  1. 因为进程有很强的独立性,所以可以将接收数据的套接字写成成员变量;父子进程间会发生写实拷贝,所有每个进程都会独立的维护自己的接收数据的套接字,完全不用担心在接收到一个全新的的连接之后会将上一个接收数据的套接字进行覆盖的情况
    在这里插入图片描述
  2. 满满的细节
    细节一子进程需要关闭父进程中的接收连接的套接字文件描述符——防止文件描述符的消耗
    细节二:为了不让父进程等待子进程退出,使用孙子进程的方式解决;子进程会立即结束,父进程也会立即回收子进程并等待下次连接
    细节三孙子进程连接结束一定要关闭文件描述符;首先关闭文件描述符是一个好习惯,其次文件描述符是使用引用计数的方式实现的,子进程退出,系统会自动回收子进程的资源,包括文件描述符,虽然在代码中没有什么危险,但是还是要关注这个细节
    细节四:虽然孙子进程会自动被系统回收,但是孙子进程也是需要手动退出,如果孙子进程没有主动退出,那么它将和父进程一样等待下次的连接
    在这里插入图片描述

✨进程池版的守护进程

  1. 手写守护进程
    SIGCLD, SIGPIPE, SIGSTOP 忽略——这三个信号在发出后,系统需要进行处理,需要从用户态转变为内核态,这个过程是很消耗资源,为了防止这种消耗,就将这三个信号进行忽略,并且这中操作在守护进程中是很常见的
    使用setsid来创建守护进程
    并将标准输入,标准输出,标准错误重定向到/dev/null文件中,/dev/null这个文件的内容会被自动丢掉,就像垃圾桶一样
    在这里插入图片描述
  2. 如果线程池先创建出来,再创建守护进程,那么守护进程不会将父进程中的线程继承下来,就导致了守护进程中虽然能将任务push进线程池,但是线程池中根本没有线程能够完成任务
    在这里插入图片描述
    所以根据他使用的时候创建的特点我们想到可以使用懒汉模式——完美解决守护进程无法继承父进程的线程的问题
    在这里插入图片描述还要注意懒汉模式是有线程安全问题,需要双层保障

http://www.ppmy.cn/devtools/14456.html

相关文章

芯科科技大大简化面向无电池物联网的能量采集产品的开发

芯科科技推出其迄今最高能量效率且支持能量采集功能的无线SoC 中国&#xff0c;北京 – 2024年4月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;…

quasar框架切换Tab页使用<keep-alive>缓存

写法1 : 使用quasar的q-tabs组件使用方法 //布局样式根据需求自己设置 <template><div class"all-Tabs"><q-tabs v-model"activeTabName" update:model-value"selectedChange"><q-tabv-for"(item, index) in cardAr…

【1429】招生管理管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 招生管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

神经网络与深度学习(四)

目录 一、循环神经网络1.1 门控循环单元(GRU)1.2 长短期记忆网络(LSTM)1.3 深度循环神经网络1.4 双向循环神经网络 二、NLP2.1 序列模型2.2 数据预处理2.3 文本预处理2.4 文本嵌入 三、RNN模型3.1 RNN概要3.2 RNN模型3.3 RNN示例 一、循环神经网络 循环神经网络&#xff08;RN…

交换机与AI的连接:构建未来智能网络的关键路径

随着信息技术的飞速发展&#xff0c;交换机和人工智能&#xff08;AI&#xff09;这两大领域正逐渐融合&#xff0c;为我们的工作和生活带来前所未有的变革。本文将探讨交换机与人工智能之间的连接&#xff0c;以及这种连接如何影响未来网络的发展。一、交换机的基本概念 交换机…

FANUC机器人socket通讯硬件配置

一、添加机器人选配包 Fanuc机器人要进行socket通讯&#xff0c;需要有机器人通讯的选配包&#xff0c;1A05B-2600-R648 User Socket Msg&#xff0c;1A05B-2600-R632 KAREL&#xff0c;1A05B-2600-R566 KAREL Diagnostic&#xff0c;1A05B-2600-J971 KAREL Use Sprt FCTN。 二…

NXP恩智浦 S32G电源管理芯片 VR5510 安全概念 Safety Concept (万字长文详解,配21张彩图)

NXP恩智浦 S32G电源管理芯片 VR5510 安全概念 Safety Concept (万字长文详解&#xff0c;配21张彩图) 1. 简介 本应用笔记描述了与S32G处理器和VR5510 PMIC相关的安全概念。该文档涵盖了S32G和VR5510的安全功能以及它们如何相互作用&#xff0c;以确保对ASIL D安全完整性级别…

考古:MFC界面的自适应缩放(代码示例)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 MFC窗体的控件的自适应缩放早期…