udp/tcp错误总结

news2024/12/24 21:05:58

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.coloradmin.cn/o/1621615.html

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

相关文章

【Unity】UnityEvent(一)

​UnityEvent----高效管理游戏事件的利器 在游戏开发中&#xff0c;事件系统是实现各种功能的关键组成部分。它允许我们将不同对象之间的交互解耦&#xff0c;使得代码更加模块化和易于维护。而UnityEvent作为Unity引擎提供的一种强大的事件系统工具&#xff0c;为开发者提供了…

CTFHub(web sql)(四)

Cookie注入 Cookie 注入的原理也和其他注入一样&#xff0c;只不过是将提交的参数已 Cookie 方式提交&#xff0c;而一般的注入是使用 GET 或者 POST 方式提交&#xff0c;GET 方式提交就是直接在网址后面加上需要注入的语句&#xff0c;POST 方式则是通过表单&#xff0c;GET …

数据仓库与数据挖掘(实验一2024.4.24)

实验准备&#xff1a; 1.下载conda 2.配置环境C:\ProgramData\miniconda3\Scripts 3.创建文件夹panda进入虚拟环境qq 激活虚拟环境&#xff1a;activate qq 启动jupyter lab&#xff08;python语言环境编译&#xff09;&#xff1a;jupyter lab 4.panda下载 &#xff08;…

【行为型模式】中介者模式

一、中介者模式概述 中介者模式定义&#xff1a;用一个中介对象来封装一系列的对象交互&#xff0c;中介者使各对象不需要显式地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式。(对象行为型模式) 中介者模式…

基于uni-app的动态表单

一、应用场景和意义 可以通过配置字段和校验规则&#xff0c;快速完成页面开发、提升开发效率 二、应用前提 形成ui/业务规范&#xff0c;最好是应用在问卷调查之类的业务 三、动态表单的功能 字段报错、快速滚动定位报错信息、支持字段值和字段规则拆分&#xff0c;便于实…

《R语言与农业数据统计分析及建模》学习——描述性统计分析

一、描述性统计概念和方法 1、概念和作用 描述性统计是对数据进行概括和描述&#xff0c;便于理解数据的特征、趋势和分布&#xff0c;帮助我们了解数据基本情况和总体特征&#xff0c;为后续更深入的数据分析和建模提供基础。 2、基础方法 &#xff08;1&#xff09;中心趋…

STM32的定时器

一、介绍 定时器的工作原理 通用定时器的介绍 定时器的计数模式 定时器时钟源 定时器溢出时间计算公式 二、使用定时器中断点亮LED灯 打开一个LED灯 更改TIME2 然后就是生成代码 三&#xff0c;代码

深度学习基础之《TensorFlow框架(15)—神经网络》

一、神经网络基础 1、什么是神经网络 人工神经网络&#xff08;Artificial Neural Network&#xff0c;简写为ANN&#xff09;。也简称为神经网络&#xff08;NN&#xff09; 是一种模仿生物神经网络&#xff08;动物的中枢神经系统&#xff0c;特别是大脑&#xff09;结构和功…

网络安全与密码学--AES加密

分组加密之AES加密算法 AES算法的诞生 python实现AES加密 AES加密详细流程 AES解密过程 AES的应用 1997年 NIST征集AES&#xff08;Advanced Encryption Standard&#xff09;2000年选中 https://www.nist.gov/ https://csrc.nist.gov/projects/block-cipher-techniques A…

WPForms Pro插件下载:简化您的在线表单构建,提升用户互动

在当今的数字化世界中&#xff0c;表单是网站与用户互动的关键。无论是收集信息、处理订单还是进行调查&#xff0c;一个好的表单可以极大地提升用户体验和转化率。WPForms Pro插件&#xff0c;作为一款专业的WordPress表单构建工具&#xff0c;旨在帮助您轻松创建美观、功能强…

如何求候选码、属性集的闭包

目录 一、基础理论 二、属性集的闭包 三、四类 四、例题 基础理论部分是我的异想天开&#xff0c;可跳过。 一、基础理论 数据库注重于研究关系&#xff0c;谈起关系&#xff0c;那么不得不提起《离散数学》&#xff0c;起初我认为求候选码的过程一定暗合《离散数学》中的…

【JavaScript】axios

基础使用 <script src"https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.min.js"></script> <script>axios.get(https://study.duyiedu.com/api/herolist).then(res> {console.log(res.data)}) </script>get - params <script s…

《智能前沿:应对ChatGPT算力挑战》

在全球人工智能热潮中&#xff0c;以 ChatGPT 为代表的 AIGC 技术引发了广泛关注。人工智能和机器学习等技术对数据规模及处理速度等提出了更高要求。在数据成为主要生产要素的当下和未来&#xff0c;如何跟上时代的发展步伐&#xff0c;构建适应 AI 需求的数据中心&#xff0c…

树莓派驱动开发----iic驱动oled屏幕篇

水一期吧&#xff0c;上效果 有点模糊&#xff0c;我直接说吧&#xff0c;修改设备树&#xff0c;iic1&#xff0c;地址0x3c&#xff0c;然后编写驱动文件&#xff0c;app文件&#xff0c;挂载驱动模块后在终端输入 /*******************************************************…

Bayes判别:统计学中的经典分类方法

在统计和机器学习领域&#xff0c;Bayes判别是一个基于概率理论的强大工具&#xff0c;用于解决分类问题。它基于Bayes定理&#xff0c;通过计算和比较后验概率来进行决策。这种方法在处理不确定性和不完整数据时表现尤为出色&#xff0c;因此在医学诊断、邮件过滤、语音识别等…

python绘制R控制图(Range Chart)

R控制图&#xff08;Range Chart&#xff09;&#xff0c;也称为范围图或移动极差图&#xff0c;是一种用于分析和控制生产过程中的变异性的统计工具。它通常与Xbar控制图&#xff08;均值图&#xff09;一起使用&#xff0c;可以提供关于生产过程变异性的额外信息。以下是R控制…

恶意软件狩猎新途径:使用.NET元数据分析跟踪恶意软件

本文由Blaze于2024年3月25日发表于其个人博客网站上。 就在不久前&#xff0c;我们意外发现了一个PureCrypter样本&#xff0c;而PureCrypter则是一款适用于各种类型恶意软件&#xff08;例如Agent Tesla和RedLine&#xff09;的加载器和混淆处理工具。深入分析之后&#xff0c…

文章杂记 | C++动态内存分配

1、C类和动态内存分配 https://blog.csdn.net/u011381222/article/details/137734622 Stringbad.h #pragma once #ifndef STRINGBAD_ #define STRINGBAD_#include<iostream>using namespace std;class Stringbad { private:char* str;//字符串地址int len; //长度st…

前端三剑客 HTML+CSS+JavaScript ④ HTML标签

祝你先于春天&#xff0c;翻过此间铮铮山峦 —— 24.4.23 一、HTML排版标签 1.标题标签 h1~h6 标签含义&#xff1a;标题 单/双标签&#xff1a;双 主要用前三个 2.段落标签 p 标签含义&#xff1a;段落 单/双标签&#xff1a;双 3.div 没有任何含…

Day17-Java进阶-网络编程(IP, 端口, 协议)TCP和UDP三次握手和四次挥手

1. 网络编程介绍 1.1 初始网络编程 1.2 网络编程三要素 1.2.1 IP InetAddress 的使用 package com.itheima.Inetaddress;import java.net.InetAddress; import java.net.UnknownHostException;public class InetAddressDemo1 {/*static InetAddress getByName(String host) 确…