网络编程day6——基于C/S架构封装的线程池
一、线程竞争基本概念
竞争与同步
同一个进程中的线程共享进程中的绝大多数资源,当它们随意竞争时可能会导致资源被破坏、脏数据、不完整问题
通过一些手段让线程在竞争资源时相互协调、避免出现以上问题,这就称为线程同步
原子操作:
操作过程中不能被打断的操作称为原子操作
临界资源、临界区、竞态条件:
能够被多个进程访问但是又无法同时访问的资源称为临界资源
每个进程中访问临界资源的那段代码称为临界区,能够被多个线程访问但是又无法同时访问的代码片段
多个线程在临界区内执行时,由于线程的执行顺序具有随机性,从而导致结果不确定,称为发生了竞态条件
二、互斥量(互斥锁)
man手册中没有全部的posix手册文档,需要安装
sudo apt-get install manpages-posix-dev
pthread_mutex_t 是一种数据类型,用来定义互斥锁变
int pthread_mutex_init(pthread_mutex_t* mutex,const pthread_mutexattr_t * attr);
功能:对互斥量进行初始化,完成后锁处于开锁状态
mutex:要初始化的互斥量
attr:互斥量的属性设置,一般默认给NULL即可
也可以在定义时通过PTHREAD_MUTEX_INITIALIZER初始化互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:对互斥量加锁,成功则返回继续执行,失败则阻塞休眠等待,直到互斥量解锁并成功加锁才唤醒返回
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:对互斥量解锁,对别人上锁的互斥量解锁,失败返回EBUSY
int pthread_mutex_trylock(pthread_mutex_t *mutex);
功能:对互斥量尝试加锁,成功返回0 失败返回EBUSY,立即返回
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁互斥量
三、读写锁
读写锁将线程访问共享数据时发出的请求分为两种:
读请求:只读取共享数据,不修改
写请求:存在修改共享数据的行为
1、当有多个线程同时发出读请求,可以同时执行
2、当有多个线程同时发出写请求,只能一个一个的执行
3、当发出读请求的线程正在执行时,发出写请求的线程必须等待前面所有读请求线程执行完后才能执行
4、当发出写请求的线程正在执行时,发出读请求的线程必须等待前面所有写请求线程执行完后才能执行
当读写锁被发出读请求的线程占用时,称为"读锁",当读写锁被发出读请求的线程占用时,称为"写锁"
1、当读写锁未被任何线程占用,称为"无锁",发出读请求、写请求的线程都可以占用,如果同时请求,默认优先给读请求占用
2、当变成读锁(多个线程占用)时,读请求的线程可以占用不会阻塞,但是写请求的线程会阻塞等待读锁解锁
3、当变成写锁(单个线程占用)时,读、写请求的线程都会阻塞等待写锁解锁
pthread_rwlock_init 初始化读写锁
pthread_rwlock_wrlock 写锁上锁
pthread_rwlock_rdlock 读锁上锁
pthread_rwlock_unlock 解锁
pthread_rwlock_destroy 销毁
四、自旋锁
在任意时刻最多只能有一个线程获取该锁
对于互斥量,如果资源已经被占用,申请者会进入休眠态
对于自旋锁,则不会引起申请者休眠,而是一直在申请处进入循环不停地查看自旋锁是否解锁,直到解锁并加锁成功后才退出循环往下执行
一般情况下使用互斥量,但是如果知道被锁住的代码执行时间很短(或者是主动让其变短),那么应该选择使用系统开销(运行态<->休眠态)较少的自旋锁更合适,因为运行态进入休眠态时,需要切换内核态 有点耗时
五、信号量
与进程间通信XSI机制中的信号量原理相似,线程之间使用的"全局"的计数器,用于控制访问有限的共享数据的线程数
sem_t 是一种数据类型,用于定义信号量变量
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化信号量
sem:要初始化的信号量
pshared:
0 只能在本进程中使用
非0 表示该信号量可以以共享内存的方式被多个进程使用,Linux不支持
value:信号量的初始值
int sem_wait(sem_t *sem);
功能:对信号量减1,如果信号量的值为0,则阻塞等待
int sem_trywait(sem_t *sem);
功能:对信号量尝试减1,如果信号量的值为0,则立即返回EAGAIN,成功返回0
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
功能:对信号量减1,如果值为0,则等待一段时间,超时还没能减则返回ETIMEDOUT
int sem_post(sem_t *sem);
功能:对信号量的值加1
int sem_destroy(sem_t *sem);
功能:销毁信号量
六、死锁
1、什么是死锁
多个进程或线程相互等待对方的资源,在得到新资源前不会释放自己的旧资源,这样就形成了循环等待,该现象称为死锁
2、产生死锁的四大必要条件
资源互斥:资源只有两种状态,可用和不可用,资源不能被同时使用,同一时刻只能被一个进程或线程使用
占用且请求:已经得到资源的进程或线程,会继续请求新的资源,并且持续占用旧资源
资源不可剥夺:当资源已经分配给进程或线程后,不能被其他进程或线程强制性获取,除非占用者主动释放
环路等待:死锁发生时,系统中必定有两个或以上的进程或线程的执行路线形成等待环路
注意:一旦产生死锁基本无解,现在的操作系统无法解决死锁,因此只能防止死锁的产生
3、防止死锁产生的方法
破坏互斥条件:
想办法让资源能够共享
缺点:受到环境或资金的影响无法让资源共享
破坏占用且请求:
采用静态预分配的方式,进程或线程在运行前尝试一次性申请所有的资源,在资源没有得到全部满足不投入运行
缺点:可能会导致系统资源的昂费,因为有些资源是很靠后才会使用,但是已经提前分配占用,导致其它不会产生死锁的进程或线程也无法使用
破坏资源不可剥夺:
当一个进程或线程占用了不可被剥夺的资源,并且请求新资源无法得到满足时,那么就把全部占用的资源主动释放,过一段时间后重新开始
缺点:该策略实现难度高,释放已经占用的资源会导致前一阶段的工作失效,还要反复申请释放资源,浪费资源、时间
破坏环路等待:
给每个资源进行编号,进程或线程都按照编号顺序来请求资源,并且必须拿到前一个编号资源后,才能去拿后一个
缺点:资源的编号顺序要相对稳定,否则在运行期间资源的增加或删减都会让该过程受极大的影响
4、如何判断死锁
1、画出资源分配图
2、简化资源分配图
3、使用死锁定理判断:看有没有环路
七、条件变量
当某些设置的条件满足时可以让线程自己进入睡眠态,也可以在另一些设置的条件满足时可以被其它线程唤醒,需要配合互斥量使用
pthread_cond_t 是一种数据类型,用于定义条件变量
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
功能:初始化条件变量,也可以直接使用PTHREAD_COND_INITIALIZER在定义时初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_destroy(pthread_cond_t *cond);
功能:销毁条件变量
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
功能:让当前线程睡入条件变量cond,并主动解锁线程自己的互斥量mutex //拿到资源先上锁,满足条件就睡眠,并且解锁
int pthread_cond_signal(pthread_cond_t *cond);
功能:唤醒因为cond睡眠的其中一个线程,线程醒来前要确保能对原来的互斥量重新加锁 //醒来之后 要能够拿到资源并上锁 与睡眠前的状态保持一致
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
功能:让当前线程睡入cond,最多睡abstime时间,超时也会返回
使用条件变量和互斥量可以实现 生产者和消费者模型
八、生产者与消费者模型 (C/S模型)
生产者:生产数据的线程
消费者:使用数据的线程
仓库:临时存储数据的缓冲区(仓库解决生产、消费不匹配的问题)
可能产生的问题:
生产快于消费:仓库爆满,撑死
消费快于生产:仓库空虚,饿死
利用条件变量来解决以上问题:
当缓冲区满的时候,生产者睡入条件变量(full),并通知消费者全部醒了(empty)
当缓冲区空的时候,消费者睡入条件变量(empty),并通知生产者全部醒来(full)
应用:利用生产者消费者模型构建 线程池
线程池的封装(gitee)
相关文章:
网络编程day6——基于C/S架构封装的线程池
一、线程竞争基本概念 竞争与同步 同一个进程中的线程共享进程中的绝大多数资源,当它们随意竞争时可能会导致资源被破坏、脏数据、不完整问题 通过一些手段让线程在竞争资源时相互协调、避免出现以上问题,这就称为线程同步 原子操作: 操作过程…...
ARM/X86工业级数据采集 (DAQ) 与控制产品解决方案
I/O设备,包括信号调理模块、嵌入式PCI/PCIE卡、便携式USB模块、DAQ嵌入式计算机、模块化DAQ系统,以及DAQNavi/SDK软件开发包和DAQNavi/MCM设备状态监测软件。 工业I/O产品适用于各种工业自动化应用,从机器自动化控制、测试测量到设备状态监测…...
【Java】Jxls--轻松生成 Excel
1、介绍 Jxls 是一个小型 Java 库,可以轻松生成 Excel 报告。Jxls 在 Excel 模板中使用特殊标记来定义输出格式和数据布局。 Java 有一些用于创建 Excel 文件的库,例如Apache POI。这些库都很好,但都是一些较底层的库,因为它们要…...
MySQL主从复制读写分离
读写分离 读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库 读写分离的好处 因为数据库的“写…...
Kafka3.0.0版本——消费者(手动提交offset)
目录 一、消费者(手动提交 offset)的概述1.1、手动提交offset的两种方式1.2、手动提交offset两种方式的区别1.3、手动提交offset的图解 二、消费者(手动提交 offset)的代码示例2.1、手动提交 offset(采用同步提交的方式…...
【AIGC专题】Stable Diffusion 从入门到企业级实战0403
一、前言 本章是《Stable Diffusion 从入门到企业级实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》第03节, 利用Stable Diffusion ControlNet Canny模型精准控制图像生成。本部分内容,位于整个Stable Diffusion生态…...
linux提权
目录 一、linux提权靶场下载与安装 二、基础提权 1.sudo提权 2.suid提权 3.taskset执行bash 三、内核提权 相关网站 https://gtfobins.github.io/#sudohttps://blog.csdn.net/weixin_43873557/article/details/113784146 一、linux提权靶场下载与安装 #下载链接 http…...
Excel VSTO开发7 -可视化界面开发
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 7 可视化界面开发 前面的代码都是基于插件启动或者退出时,以及Excel Application的相关事件,在用户实际操作…...
英文科技论文写作与发表-投稿到发表(第6章)
1 投稿到发表 本章介绍典型会议和期刊从投稿到最终录用或退稿的全过程,期刊从投稿到最终录用或退稿的过程在各种不同学科领域差别不大。会议主要针对计算机科学及其相关领域(如电子、信息、其他工程类)的会议。最后总结几条怎样提高论文命中…...
2.4.3 【MySQL】设置系统变量
2.4.3.1 通过启动选项设置 大部分的系统变量都可以通过启动服务器时传送启动选项的方式来进行设置。如何填写启动选项就是下面两种方式: 通过命令行添加启动选项。 在启动服务器程序时用这个命令: mysqld --default-storage-engineMyISAM --max-conn…...
【Redis】2、Redis持久化和性能管理
Redis 高可用 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供…...
MIT6.S081实验环境搭建
MIT6.S081 lab 环境搭建 本文参考了MIT的官方指南和知乎文章环境搭建 step1 首先需要一个ubuntu20.04的系统,我使用的是vscode的WSL2连接的ubuntu20.04,使用virtual box建一个ubuntu20.04的虚拟机应该也可以。 可以用 lsb_release -a 查看一下自己ub…...
spring spring-boot spring-cloud spring-cloud-alibaba之间版本对应关系
spring 版本与 jdk 的对应关系 https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions 从 spring 6.0 开始使用 jdk 17 进行编译 对应的相关 servlet 容器(tomcat、undertow、jetty等)的 servlet 规范转移到 eclipse&…...
Docker技术入门 | Part01:Docker简介
文章目录 1 虚拟化技术2 Docker概述2.1 Docker能解决的问题2.2 Docker介绍2.3 为什么使用Docker2.4 Docker特点2.5 Docker应用场景 3 Docker与虚拟机对比3.1 Docker和虚拟机组成结构3.2 Docker和虚拟机的不同点 4 Docker基本概念4.1 Docker引擎4.2 Docker基本架构4.3 Docker容器…...
Apache实现weblogic集群配置
安装apache,安装相对稳定的版本。如果安装后测试能否正常启动,可以通过访问http://localhost/进行测试。安装Weblogic,参见文档将bea安装目录 weblogic81/server/bin 下的 mod_wl_20.so 文件copy到 apache安装目录下Apache2/modules/目录下A…...
Java面试题总结2023
Java面试题总结2023 基础String中常用的方法 与 equals的区别值传递和引用传递数组和集合的区别成员变量和局部变量的区别final和finally和finalize的区别Cookie和Session的的区别接口分类接口和抽象类的区别说说你对抽象类的理解String/StringBuffer/StringBuilderjdk1.8的新特…...
采用ROUANT 方法对 nex-gddp-cmip6 数据进行精度校正
专题一 CMIP6中的模式比较计划 1.1 GCM介绍全球气候模型(Global Climate Model, GCM),也被称为全球环流模型或全球大气模型,是一种用于模拟地球的气候系统的数值模型。这种模型使用一系列的数学公式来描述气候系统的主要组成部分…...
超级电容-电池-超级电容混合储能系统能量管理simulink仿真建模模型
建立混合储能系统模型 在Simulink中,首先需要建立一个超级电容和蓄电池并联的混合储能系统模型。其中,超级电容和蓄电池的荷电状态(SOC)需要根据实际情况进行管理。荷电状态可以通过对电池和超级电容的电压、电流等进行测量&…...
最新仿闲鱼链接+独立后台管理 跳转APP
2024最新仿xy链接源码 后台一键生成链接,后台管理教程:解压源码,修改数据库config/Congig 不会可以看源码里有教程 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...
DoIP协议——汽车以太网应用介绍
DoIP目录 前言一、DoIP术语和缩写二、网络拓扑三、DoIP数据基本结构四、应用场景4.1 直接点对点连接4.2 多台外部测试设备分别和多台汽车在局域网内通过交换机点对点连接4.3 一台外部测试设备跨越本地网络与多台车辆连接4.4 外部测试设备的多个应用层实体(在一台硬件或多台硬件…...
标准C++day1——名字空间和堆内存管理
一、C介绍 本贾尼.斯特劳斯特卢普,于1979年在贝尔实验室负责分析UNIX系统内核流量的分布情况时,特别希望有一种更加模块化的工具,于1979.10开始着手研发一款新的编程语言,在C语言的基础上增加了面向对象的机制,也就是C…...
草图大师SketchUp Pro 2023 for Mac
SketchUp Pro 2023 for Mac(草图大师)是一款专业的三维建模软件,由Trimble Inc.开发。它可以用于创建、修改和分享3D模型,包括建筑、家具、景观等。 SketchUp Pro 2023 for Mac提供了简单易学的用户界面和强大的工具集࿰…...
doris docker环境编译部署
1.准备doris docker环境 xiuchenggongxiuchengdeMacBook-Pro bin % docker pull apache/doris:build-env-ldb-toolchain-latestbuild-env-ldb-toolchain-latest: Pulling from apache/doris eeedae70be19: Pull complete a3ed95caeb02: Pull complete Digest: sha256:63d9a9…...
java封装国密SM4为 jar包,PHP调用
java封装国密SM4为 jar包,PHP调用 创建java工程引入SM4 jar包封装CMD可调用jar包PHP 传参调用刚用java弄了个class给php调用,本以为项目上用到java封装功能的事情就结束了,没想到又来了java的加密需求,这玩意上头,毕竟不是强项,没办法,只好再次封装。 但是这次的有点不…...
微信小程序 wx:if使用
在微信小程序中,可以使用wx:if指令来控制某个元素是否需要被渲染到页面上。根据条件表达式的结果,wx:if指令决定元素是否显示。 下面是使用wx:if的基本示例: <view><view wx:if"{{condition}}"><!-- 条件为真时显…...
SpringBoot环境MongoDB分页+去重+获取去重后的原始数据
最近有个比较复杂的MongoDB查询需求, 要求1:获取最近订单表中的请求参数信息,并需要按照请求参数中的账号进行去重 要求2:数据量可能比较大,因此需要做分页查询 研究了大半天,终于搞出了解决方案࿰…...
Vuex核心概念 - actions 和 getters
文章目录 actions 和 getters一、actions作用使用目的: 二、actions的使用执行原理代码示例: 三、actions中的辅助函数mapActions代码示例: 四、核心-getters1. 什么是getters?2. getters的作用:3. 访问 getters 的两种…...
51单片机的简易计算器数码管显示仿真设计( proteus仿真+程序+原理图+报告+讲解视频)
51单片机的简易计算器数码管显示仿真设计 1.主要功能:2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接 51单片机的简易计算器数码管显示仿真设计( proteus仿真程序原理图报告讲解视频) 仿真图proteus7.8及以上 程序编译器…...
Qt版本的冷知识
Qt4.8.7是Qt4的终结版本,是Qt4系列版本中最稳定最经典的(很多嵌入式板子还是用Qt4.8),其实该版本是和Qt5.5差不多时间发布的。参考链接 https://www.qt.io/blog/2015/05/26/qt-4-8-7-released https://blog.qt.io/blog/2015/07/01…...
[C++ 学习] 控制信号
// // Created by ubuntu on 9/6/23. // #include<iostream> #include<unistd.h> #include <signal.h>using namespace std; void EXIT(int sig){cout << "收到了信号:" << sig << endl;cout << "正在释放…...
贵阳东方蜜蜂网站建设/1688自然排名怎么做好
大多数行业都免不了此类琐碎繁杂的工作,而他们却又占用很多时间、很容易让人产生厌倦心理。如果被迫耗在这些数据整理的事情上,工作效率自然难以提高。这时Python提供了一种解决的方法。只要第一次花点时间做好小工具,后期工作便可以一键完成…...
网站移动端是什么问题/推广费用一般多少
我试图从web中读取python模块中的一些数据.我设法阅读,但在解析这些数据和获取所需信息方面遇到一些困难.我的代码如下.任何帮助表示赞赏.#!/usr/bin/python2.7 -ttimport urllibimport urllib2def Connect2Web():aResp urllib2.urlopen("https://uniservices1.uobgroup.…...
做谷歌网站使用什么统计代码吗/怎么做谷歌推广
1. 行内样式 通过 ele.style.styleName 获取 (可读写) 2. 内联样式和外联样式 // 兼容写法,获取任意元素的css样式 (只读) function getStyle(ele,styleName){if(ele.currentStyle){return ele.currentStyle[styleName];}else{return window.getCompu…...
专业建设网站技术/百度手机快速排名点击软件
Prometheus介绍 使用领先的开源监控解决方案为您的指标和警报提供支持 在项目中,如果我们都使用 k8s 部署,那么就需要集成Prometheus 来监控和收集指标来提供告警功能,这对于企业内是有非常打的作用,Prometheus 天然支持ÿ…...
上海营销网站建设定制服务/热搜词排行榜关键词
C语言练习:第二大整数问题描述编写一个程序,读入一组整数(不超过20个),当用户输入0时,表示输入结束。然后程序将从这组整数中,把第二大的那个整数找出来,并把它打印出来。说明:(1)0表示输入结束…...
西安企业模板网站建设/排名检测
如果还不行,那么再极端的设置,在IDEA启动的时候强制设置为UTF-8: 打开增加-Dfile.encodingUTF-8,重启Intellij IDEA 再或者直接在项目运行的时候加入UTF-8的设置 如果还是不行,那么你可能装了一个假的IDEA。>如有问…...