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

网站排名优化公司推荐济宁医院网站建设

网站排名优化公司推荐,济宁医院网站建设,wordpress文字保存,wordpress弹性搜索https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到#xff0c;Linux以进程为单位组织操作#xff0c;Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统#xff0c;但Linux的多线程…https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到Linux以进程为单位组织操作Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统但Linux的多线程在逻辑和使用上与真正的多线程并没有差别。 多线程 我们先来看一下什么是多线程。在Linux从程序到进程中我们看到了一个程序在内存中的表示。这个程序的整个运行过程中只有一个控制权的存在。当函数被调用的时候该函数获得控制权成为激活(active)函数然后运行该函数中的指令。与此同时其它的函数处于离场状态并不运行。如下图所示: Linux从程序到进程 我们看到各个方块之间由箭头连接。各个函数就像是连在一根线上一样计算机像一条流水线一样执行各个函数中定义的操作。这样的一个程序叫做单线程程序。 多线程就是允许一个进程内存在多个控制权以便让多个函数同时处于激活状态从而让多个函数的操作同时运行。即使是单CPU的计算机也可以通过不停地在不同线程的指令间切换从而造成多线程同时运行的效果。如下图所示就是一个多线程的流程: main()到func3()再到main()构成一个线程此外func1()和func2()构成另外两个线程。操作系统一般都有一些系统调用来让你将一个函数运行成为一个新的线程。 回忆我们在Linux从程序到进程中提到的栈的功能和用途。一个栈只有最下方的帧可被读写。相应的也只有该帧对应的那个函数被激活处于工作状态。为了实现多线程我们必须绕开栈的限制。为此创建一个新的线程时我们为这个线程建一个新的栈。每个栈对应一个线程。当某个栈执行到全部弹出时对应线程完成任务并收工。所以多线程的进程在内存中有多个栈。多个栈之间以一定的空白区域隔开以备栈的增长。每个线程可调用自己栈最下方的帧中的参数和变量并与其它线程共享内存中的Textheap和global data区域。对应上面的例子我们的进程空间中需要有3个栈。 (要注意的是对于多线程来说由于同一个进程空间中存在多个栈任何一个空白区域被填满都会导致stack overflow的问题。) 并发 多线程相当于一个并发(concunrrency)系统。并发系统一般同时执行多个任务。如果多个任务可以共享资源特别是同时写入某个变量的时候就需要解决同步的问题。比如说我们有一个多线程火车售票系统用全局变量i存储剩余的票数。多个线程不断地卖票(i i - 1)直到剩余票数为0。所以每个都需要执行如下操作: /*mu is a global mutex*/while (1) {    /*infinite loop*/if (i ! 0) i i -1else {printf(no more tickets);exit();} } 如果只有一个线程执行上面的程序的时候(相当于一个窗口售票)则没有问题。但如果多个线程都执行上面的程序(相当于多个窗口售票), 我们就会出现问题。我们会看到其根本原因在于同时发生的各个线程都可以对i读取和写入。 我们这里的if结构会给CPU两个指令, 一个是判断是否有剩余的票(i ! 0), 一个是卖票 (i i -1)。某个线程会先判断是否有票(比如说此时i为1)但两个指令之间存在一个时间窗口其它线程可能在此时间窗口内执行卖票操作(i i -1)导致该线程卖票的条件不再成立。但该线程由于已经执行过了判断指令所以无从知道i发生了变化所以继续执行卖票指令以至于卖出不存在的票 (i成为负数)。对于一个真实的售票系统来说这将成为一个严重的错误 (售出了过多的票火车爆满)。 在并发情况下指令执行的先后顺序由内核决定。同一个线程内部指令按照先后顺序执行但不同线程之间的指令很难说清除哪一个会先执行。如果运行的结果依赖于不同线程执行的先后的话那么就会造成竞争条件(race condition)在这样的状况下计算机的结果很难预知。我们应该尽量避免竞争条件的形成。最常见的解决竞争条件的方法是将原先分离的两个指令构成不可分隔的一个原子操作(atomic operation)而其它任务不能插入到原子操作中。 多线程同步 对于多线程程序来说同步(synchronization)是指在一定的时间内只允许某一个线程访问某个资源 。而在此时间内不允许其它的线程访问该资源。我们可以通过互斥锁(mutex)条件变量(condition variable)和读写锁(reader-writer lock)来同步资源。 1) 互斥锁 互斥锁是一个特殊的变量它有锁上(lock)和打开(unlock)两个状态。互斥锁一般被设置成全局变量。打开的互斥锁可以由某个线程获得。一旦获得这个互斥锁会锁上此后只有该线程有权打开。其它想要获得互斥锁的线程会等待直到互斥锁再次打开的时候。我们可以将互斥锁想像成为一个只能容纳一个人的洗手间当某个人进入洗手间的时候可以从里面将洗手间锁上。其它人只能在互斥锁外面等待那个人出来才能进去。在外面等候的人并没有排队谁先看到洗手间空了就可以首先冲进去。 上面的问题很容易使用互斥锁的问题解决每个线程的程序可以改为: /*mu is a global mutex*/while (1) { /*infinite loop*/mutex_lock(mu);       /*aquire mutex and lock it, if cannot, wait until mutex is unblocked*/if (i ! 0) i i - 1;else {printf(no more tickets);exit();}mutex_unlock(mu);     /*release mutex, make it unblocked*/ } 第一个执行mutex_lock()的线程会先获得mu。其它想要获得mu的线程必须等待直到第一个线程执行到mutex_unlock()释放mu才可以获得mu并继续执行线程。所以线程在mutex_lock()和mutex_unlock()之间的操作时不会被其它线程影响就构成了一个原子操作。 需要注意的时候如果存在某个线程依然使用原先的程序 (即不尝试获得mu而直接修改i)互斥锁不能阻止该程序修改i互斥锁就失去了保护资源的意义。所以互斥锁机制需要程序员自己来写出完善的程序来实现互斥锁的功能。我们下面讲的其它机制也是如此。 2) 条件变量 条件变量是另一种常用的变量。它也常常被保存为全局变量并和互斥锁合作。 假设这样一个状况: 有100个工人每人负责装修一个房间。当有10个房间装修完成的时候老板就通知相应的十个工人一起去喝啤酒。 我们如何实现呢老板让工人在装修好房间之后去检查已经装修好的房间数。但多线程条件下会有竞争条件的危险。也就是说其他工人有可能会在该工人装修好房子和检查之间完成工作。采用下面方式解决 /*mu: global mutex, cond: global codition variable, num: global int*/mutex_lock(mu)num num 1; /*worker build the room*/if (num 10) { /*worker is within the first 10 to finish*/cond_wait(mu, cond);     /*wait*/printf(drink beer); } else if (num 11) { /*workder is the 11th to finish*/cond_broadcast(mu, cond);        /*inform the other 9 to wake up*/ }mutex_unlock(mu); 上面使用了条件变量。条件变量除了要和互斥锁配合之外还需要和另一个全局变量配合(这里的num, 也就是装修好的房间数)。这个全局变量用来构成各个条件。 具体思路如下。我们让工人在装修好房间(num num 1)之后去检查已经装修好的房间数( num 10 )。由于mu被锁上所以不会有其他工人在此期间装修房间(改变num的值)。如果该工人是前十个完成的人那么我们就调用cond_wait()函数。 cond_wait()做两件事情一个是释放mu从而让别的工人可以建房。另一个是等待直到cond的通知。这样的话符合条件的线程就开始等待。 当有通知(第十个房间已经修建好)到达的时候condwait()会再次锁上mu。线程的恢复运行执行下一句prinft(drink beer) (喝啤酒)。从这里开始直到mutex_unlock()就构成了另一个互斥锁结构。 那么前面十个调用cond_wait()的线程如何得到的通知呢我们注意到elif if即修建好第11个房间的人负责调用cond_broadcast()。这个函数会给所有调用cond_wait()的线程放送通知以便让那些线程恢复运行。 条件变量特别适用于多个线程等待某个条件的发生。如果不使用条件变量那么每个线程就需要不断尝试获得互斥锁并检查条件是否发生这样大大浪费了系统的资源。 3) 读写锁 读写锁与互斥锁非常相似。r、RW lock有三种状态: 共享读取锁(shared-read), 互斥写入锁(exclusive-write lock), 打开(unlock)。后两种状态与之前的互斥锁两种状态完全相同。 一个unlock的RW lock可以被某个线程获取R锁或者W锁。 如果被一个线程获得R锁RW lock可以被其它线程继续获得R锁而不必等待该线程释放R锁。但是如果此时有其它线程想要获得W锁它必须等到所有持有共享读取锁的线程释放掉各自的R锁。 如果一个锁被一个线程获得W锁那么其它线程无论是想要获取R锁还是W锁都必须等待该线程释放W锁。 这样多个线程就可以同时读取共享资源。而具有危险性的写入操作则得到了互斥锁的保护。 我们需要同步并发系统这为程序员编程带来了难度。但是多线程系统可以很好的解决许多IO瓶颈的问题。比如我们监听网络端口。如果我们只有一个线程那么我们必须监听接收请求处理回复再监听。如果我们使用多线程系统则可以让多个线程监听。当我们的某个线程进行处理的时候我们还可以有其他的线程继续监听这样就大大提高了系统的利用率。在数据越来越大服务器读写操作越来越多的今天这具有相当的意义。多线程还可以更有效地利用多CPU的环境。 (就像做饭一样不断切换去处理不同的菜。) 本文中的程序采用伪C的写法。不同的语言有不同的函数名(比如mutex_lock)。这里关注的是逻辑上的概念而不是具体的实现和语言规范。 总结 multiple threads, multiple stacks race condition mutex, condition variable, RW lock
http://www.pierceye.com/news/844093/

相关文章:

  • 无锡网站设wordpress营销模板
  • 建站哪个好一点wordpress直达按钮
  • 卢松松网站的百度广告怎么做的小程序开发成都公司
  • 导航网站头部代码android开发者官网
  • 网站设计需求分析报告做漫画的网站有哪些
  • 做什么网站吸引人sinaapp wordpress 固定链接
  • 东莞做网站怎么样搜狐综合小时报2022113011
  • 校园网站的意义融资渠道
  • 做网站上海公司自己制作一个网站需要什么软件
  • 铜川做网站电话app开发程序
  • 自助建微网站备案后修改网站名称
  • 免费网站正能量网站如何后台管理
  • 网站开发的质量标准网站如何做自适应
  • 黄南州wap网站建设公司wordpress里面怎么加链接
  • 五分钟自己创建网站的方法免费试用网站空间
  • 安徽平台网站建设找哪家辽宁建设工程信息网审核
  • 余姚住房和建设局网站10元备案域名购买
  • 企业网站制作公司盈利做支付行业招代理一般上什么网站
  • 网站制作电话wordpress支持PHP吗
  • 天津网站推广宣传拓者设计吧室内设计
  • 建设 信用中国 网站淘宝购物
  • 义乌论坛网站建设怎样建设智能网站
  • 重庆做网站 外包公司建设校园网站的必要性
  • 做我女朋友好不好套路网站html5网页设计实训总结
  • 怎样给网站登录界面做后台seo研究中心官网
  • 养生类网站源码dreamwear网页制作
  • 北京装修平台网站网页设计公司企业文化
  • 上海临平路网站建设网站建设设计制作方案与价格
  • seo三人行网站免费电商网站建设
  • seo蒙牛伊利企业网站专业性诊断.win域名做网站怎么样