当前位置: 首页 > news >正文

曲靖网站建设dodoco网站如何创建首页

曲靖网站建设dodoco,网站如何创建首页,做电影网站要几G空间的,WordPress多功能投稿文章目录1. 互斥1.1 为什么需要互斥1.2 互斥锁1.3 初谈互斥与同步1.4 锁的原理1.5 可重入VS线程安全1.6 死锁1.7 避免死锁的算法#xff08;扩展#xff09;序#xff1a;在上一章中我们知道了线程控制的三个角度#xff1a;线程创建、线程等待和线程终止#xff0c;分别从… 文章目录1. 互斥1.1 为什么需要互斥1.2 互斥锁1.3 初谈互斥与同步1.4 锁的原理1.5 可重入VS线程安全1.6 死锁1.7 避免死锁的算法扩展序在上一章中我们知道了线程控制的三个角度线程创建、线程等待和线程终止分别从接口以及参数的意义和功能的角度来了解以及最后深入原生线程库了解用户级线程与内核轻量型进程的关系。而本章将从线程的同步与互斥的角度来带大家了解什么是互斥和同步以及为什么要互斥和同步等一系列问题。 上一章线程控制的知识补充 线程分离: pthread_detach函数可以是线程组内其他线程对目标线程进行分离也可以是线程自己分离分离后的线程不可被等待如果强行等待也会返回错误码22。 问题一为什么要有线程分离呢 如果不关心线程的返回值join是一种负担这个时候我们可以告诉系统当线程退出时自动释放线程资源。 归根结底我们让线程分离其实就是更改线程的原生线程库里的tcb内的分离的属性而pthread_join就是识别到了该分离属性被更改为已分离所以才会直接返回一个错误码。 1. 互斥 1.1 为什么需要互斥 多线程抢票模型代码演示 #includeiostream #includeunistd.h #includepthread.h #includestring #includevector using namespace std;#define NUM 4int ticket 100;//用多线程模拟一轮抢票class ThreadData { public:ThreadData(int number){_thread_name thread- to_string(number);} public:string _thread_name; };void* GetTicket(void* args) {ThreadData* tdstatic_castThreadData*(args);const char* name td-_thread_name.c_str();while(true){if(ticket0){usleep(5000);printf(i am %s,get a ticket:%d\n,name,ticket);ticket--;}else break;}printf(%s ... quit\n,name);return nullptr;} int main() {vectorpthread_t tids;vectorThreadData* thread_datas;for(int i0;iNUM;i){pthread_t tid;ThreadData* tdnew ThreadData(i);thread_datas.push_back(td);pthread_create(tid,nullptr,GetTicket,thread_datas[i]);tids.push_back(tid);}for(auto e :tids){pthread_join(e,nullptr);}for(auto e :thread_datas){delete e;}return 0; }结果如图 那么问题来了抢票模型中为什么抢票抢到最后竟然抢到了负数这个问题我们暂且不谈我们继续往下说。 要想了解为什么会出现这样的情况我们首先就要知道既然ticket出现了负数就说明ticket–出现了问题共享数据------数据不一致问题肯定和多线程并发访问是有关系的对一个全局变量进行多线程并发–或操作是否是安全的所以这个–操作不是原子的所以也不是安全的。 既然–操作是不安全的不是原子的那我们要了解ticket–究竟要有哪些步骤 第一个步骤先将ticket读入到CPU的寄存器当中 第二个步骤CPU内部进行–操作 第三个步骤将计算结果写回内存 但是想要了解为什么会出现这样的情况我们还要了解一个额外的知识点寄存器不等于寄存器的内容线程在执行的时候将共享数据加载到CPU寄存器的本质把数据的内容变成了自己的上下文 — 这样的数据以拷贝的形式给自己单独拿了一份 既然ticket–是有三个步骤组成如果在这三个步骤之内发生了线程切换就会导致数据不一致的问题 假设当前抢票的进程中票有1000张该进程内有两个线程正在抢票此时thread-1线程正在实现抢票刚完成第一步将内存中的数据读入寄存器中也就是读入该线程的上下文中如果此时来了第二个线程thread-2也要实行抢票将thread-1线程切换了thread-1线程就会带着这个1000的数据一起离开等待线程再次切换回来 当线程切换到thread-2线程假设此时thread-2线程在下一次线程切换的时间片内进行了100次抢票的动作此时的票数就由1000变成了900 当thread-2线程抢了100张票后将寄存中的900写回给内存中的ticket此时thread-1线程切换回来了thread-2线程就要带着自己的硬件上下文走于是thread-2就将寄存器中的900带走了thread-1线程切换回来后会将之前就带走的寄存器中的1000带回来在放入到寄存器中即恢复上下文。 然后此时thread-1会继续执行未完成的动作继续执行第二步和第三步。 这就会导致thread-2辛辛苦苦抢的票将1000变成900结果thread-1线程切换回来后就变成了999。 现在让我们来回答最开始的那个问题为什么ticket会出现负数 假设此时的实际票数小于线程数此时有四个线程但票只有两个了别忘了ticket0也是运算逻辑运算所以此时同时有4个线程都对ticket进行了逻辑运算此时票有两个都是大于0此时四个线程都进入了该循环内都可以进行ticket–这也就是为什么会出现了负数 1.2 互斥锁 怎么解决上述的一些列问题 对共享数据的任何访问保证任何时候只有一个执行流进行访问—互斥 而想要实现互斥就要引入互斥锁的概念 锁资源的定义初始化和释放 pthread_mutex_t是库提供的一种数据类型 pthread_mutex_init第一个参数传锁第二个参数传锁的各种参数默认传nullptr pthread_mutex_destroy (如果用pthread_mutex_t mutex PTHREAD_MUTEX_INITIALZER进行全局变量的初始化就不用调用pthread_mutex_destroy函数进行释放 一种临界资源由多个线程访问如果想要保证临界资源的安全就必须让这个多个线程访问同一把锁 锁的申请和释放 pthread_mutex_lock pthread_mutex_unlock 其中的pthread_mutex_trylock函数就是加锁的非阻塞版本 到这一步大家只能对锁有个印象没法深刻知道锁的作用和锁的使用接下来我将改进原本的多线程抢票模型的代码用互斥锁来使原版中的多线程导致的数据不一致问题得到解决 互斥锁版的多线程抢票模型代码演示 #includeiostream #includeunistd.h #includepthread.h #includestring #includevectorusing namespace std;#define NUM 5int ticket 100;//用多线程模拟一轮抢票class ThreadData { public:ThreadData(int number,pthread_mutex_t* lock){_thread_name thread- to_string(number);_locklock;} public:string _thread_name;pthread_mutex_t *_lock; };void* GetTicket(void* args) {ThreadData* tdstatic_castThreadData*(args);const char* name td-_thread_name.c_str();while(true){pthread_mutex_lock(td-_lock);if(ticket 0){//usleep(5000);printf(i am %s,get a ticket:%d\n,name,ticket);ticket--;}else{pthread_mutex_unlock(td-_lock);break;}pthread_mutex_unlock(td-_lock);usleep(5000);}printf(%s ... quit\n,name);return nullptr; }int main() {pthread_mutex_t lock;pthread_mutex_init(lock,nullptr);vectorpthread_t tids;vectorThreadData* thread_datas;for(int i0;iNUM;i){pthread_t tid;ThreadData* tdnew ThreadData(i,lock);thread_datas.push_back(td);pthread_create(tid,nullptr,GetTicket,thread_datas[i]);tids.push_back(tid);}for(auto e :tids){pthread_join(e,nullptr);}for(auto e :thread_datas){delete e;}pthread_mutex_destroy(lock);return 0; }对于上面一段代码我们用锁将临界资源锁住同一时间只能有一个线程进行访问从而实现对临界资源的保护 其中被锁保护的资源叫做临界资源某几段访问临界资源的代码区叫做临界区 加锁的本质是用时间来换安全 加锁的表现线程对临界区代码的串行执行 加锁原则尽量保证临界区代码越少越好。 申请锁成功了才能往后执行不成功就会阻塞等待等待锁资源释放 不同线程对于锁的竞争能力可能会不同在纯互斥环境中如果锁分配不够合理容易导致其他线程的饥饿问题-----不是说只要有互斥就必有饥饿适合纯互斥场景就用互斥。 1.3 初谈互斥与同步 目前我们对于锁的概念已经有了一个清晰的认识了但是我们发现了一个新的问题当一个线程申请锁完成对临界资源的访问后释放锁后该线程可能也会申请锁这就可能出现一个线程一直在申请和释放锁导致其他线程没办法申请到锁对于这种情况就要深入了解同步的概念来解决新出现的问题现在让我们更加深入的了解互斥与同步吧 现在有一个vip自习室 vip自习室规定1. 外面的同学想要进入vip自习室必须排队。2. 出来的同学将钥匙放好后不能立马重新拿钥匙进vip自习室如果想要再次进入自习室则必须排到队列的尾部进行排队 vip自习室的规则让所有的同学线程按照一定的顺序拿到钥匙锁进入vip自习室而按照一定的顺序性获取资源的模式就是同步 1.4 锁的原理 锁本身也是一种临界资源所以。申请锁和释放锁本身就被设计成为了原子性操作了问题如何做到的 在临界区中线程可以被切换吗可以切换在线程被切出去的时候是持有锁被切走的。该线程即使被切换走了照样没有任何线程能进入资源临界区访问临界资源 对于其他线程来讲一个线程要么没有锁要么释放锁。当前线程访问临界区的过程对于其他线程就是原子的 问题一为什么说ticket–不是原子的因为该语句会变成多条汇编语句在该汇编语句的中间如果有其他线程也在执行就会出错出现不一致的情况换言之只要汇编语句只有一条就没有问题所以原子只有一条汇编语句就是原子的 lock的汇编语句xchqb %almutex Xchqb交换的本质把内存中的数据共享交换到CPU的寄存器中把数据交换到线程的硬件的上下文中—把一个共享的锁让一个线程以一条汇编语句的方式交换到自己的上下文中这就叫做当前线程持有锁了 unlock的汇编语句movb $1mutex将一个共享的锁从线程的上下文中拿出来。这就叫做当前线程释放锁了 1.5 可重入VS线程安全 线程安全的概念多个线程并发同一段代码时不会出现不同的结果。常见对全局变量或者静态变量进行操作 并且没有有锁保护的情况下会出现该问题。 重入的概念同一个函数被不同的执行流调用当前一个流程还没有执行完就有其他的执行流再次进入我们称之为重入。一个函数在重入的情况下运行结果不会出现任何不同或者任何问题则该函数被称为可重入函数、不则具不可重入函数。 可重入与线程安全联系: 函数是可重入的那就是线程安全的。 函数是不可重入的那就不能由多个线程使用有可能引发线程安全问题。 如果一个函数中有全局变量那么这个函数既不是线程安全也不是可重入的。 可重入与线程安全区别: 可重入函数是线程安全函数的一种。 线程安全不一定是可重入的而可重入函数则一定是线程安全的。 如果将对临界资源的访问加上锁则这个函数是线程安全的但如果这个重入函数若锁还未释放则会产生死锁因此是不可重入的。 1.6 死锁 死锁的概念 死锁是指在一组进程中的各个进程均占有不会释放的资源但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。 死锁产生的必要条件 互斥条件一个资源每次只能被一个执行流使用前提 请求与保持条件一个执行流因请求资源而阻塞时对已获得的资源保持不放原则 不剥夺条件:一个执行流已获得的资源在末使用完之前不能强行剥夺原则 死锁产生的充分条件 循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系重要条件 这三个必要条件必须同时满足才是死锁。 如何避免死锁问题 1. 破坏死锁的四个必要条件只需要一个不满足就可以了 2. 加锁顺序一致 3. 避免锁未释放的场景 4. 资源一次性分配 1.7 避免死锁的算法扩展 银行家算法 下面是银行家算法的模拟实现感兴趣的小伙伴可以去了解 银行家算法避免死锁 总结 本篇博客先是补充了上一章中对于线程分离的知识缺失的内容补全而后从一小段代码出发在多线程的抢票模型下我们逐步发现多线程带来的问题并逐步解决为了解决这些问题我们先后引入了互斥和同步的概念最后有队线程安全问题和可重入的问题进行了了解并讲述了死锁的概念及其产生的条件最后以避免死锁的银行家算法结尾谢谢大家的支持
http://www.zqtcl.cn/news/952211/

相关文章:

  • 企业网站功能怎么设计wordpress文章图片轮播
  • 网站后台登陆验证码不对阳江房产网楼市数据
  • 营销型网站建设遨龙仙居住房和城乡建设规划局网站
  • 中国做视频网站有哪些淘宝做详情页代码网站
  • 网站开发一般多钱在网站设计公司上班好吗
  • 餐饮连锁企业网站建设方案北京软件研发公司
  • 外国网站架构新闻稿
  • 营销网站建设企划案例友情链接怎么添加
  • seo网站搜索优化目前好的推广平台
  • 快速搭建网站页面黄页88网免费发布信息
  • 做网站能赚吗网址大全查询ip地址
  • html5网站正在建设中商城网站系统
  • 室内设计网课北京网站优化前景
  • 北京 网站建设 知乎上海公司买新能源车
  • 成都微网站wordpress 购买
  • 网站开发一般要用到哪些软件软件开发工程师机构
  • dj网站开发建设网站备案 换空间
  • 网站建设哪家最好网站开发怎么报价
  • app 微商城网站建设网站建设流程百科
  • 网站短期培训学校小说网站怎么建设的
  • 最简单的免费网站制作模板电子商务 网站系统
  • 网站域名备案授权书网站建设长春
  • 网站维护主要从哪几个方面做seo营销的概念
  • 北京网站建设营销网站策划案4500
  • 网站建设售后培训wordpress 过滤html
  • 湖北森泰建设集团有限公司网站国外产品设计网站推荐
  • 网站建设与代运营产品介绍排版网页设计教程
  • 音乐网站排名搜索引擎网络推广方法
  • asp.net 企业网站昆明高端seo怎么做
  • 图书馆网站建设需求方案企业网站背景图片