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

win2003 建设网站企业推广网

win2003 建设网站,企业推广网,郑州网站建设到诺然,自考大型网站开发工具怎样在不加锁的情况下解决线程安全问题,你需要了解lock free和wait free这两个概念,在此之前我们先从最简单的有锁编程开始。 我们知道,多线程同时修改共享变量时会出现数据不一致的问题,比如多个线程同时对一个变量加1&#xff…

怎样在不加锁的情况下解决线程安全问题,你需要了解lock free和wait free这两个概念,在此之前我们先从最简单的有锁编程开始。

我们知道,多线程同时修改共享变量时会出现数据不一致的问题,比如多个线程同时对一个变量加1,假设count的初始值为0:

int count;void add() {++count;
}

如果只有一个线程调用add函数,那么什么问题都没有,但如果多个线程同时调用上述函数,比如10个线程都调用一遍,那么count值最后不一定等于0,原因在于对count加1的操作不是原子的 。

所谓某个操作是原子的是指CPU要么执行该操作,要么不执行该操作,不存在中间状态,但上述对count加1的操作经过编译器处理后会生成几条对应的机器指令,所以该操作不是原子的。

那么怎样才能让其变成原子的呢?很简单,加一把锁。

int count;
mutex mtx; // 锁void add() {mtx.lock();++count;mtx.unlock();
};

现在我们用一把锁将对count的操作保护了起来,此时你可以将mtx.lock()以及mtx.unlock()中间的代码看成原子的,CPU要完全执行完对count的加1要么根本不会操作count,这样上述程序的运行结果就是我们想要的了。

这是怎样做到呢?这就要说到操作系统了,千万不要小瞧了上面的mutex这把锁,这把锁的背后相当复杂,因为这涉及到了操作系统。

假设现在有三个线程,各自运行在不同的CPU核心上,每个方框代表一个时间片:

T1时间片这三个线程都在调用add函数,线程A拿到锁,A可以继续向前推进,但B和C就没这么幸运了,此时操作系统将剥夺线程B和C继续持有CPU的权利,将其分配给其它具备执行条件的线程,这就是操作系统中所谓的挂起,注意,这个过程相当复杂,因为这涉及到用户态与内核态的切换以及线程的切换等等。

此时来到T2时间片,线程A继续向前推进,线程B和C则被按下暂停键。

T3时间片,然而就在线程A拿到锁运行时因为某些原因像高优先级线程枪占之类导致操作系统也剥夺了线程A继续持有CPU的权利,糟糕的是,因为线程A此时持有锁,而线程A又无法继续向前推进,这就进一步使得线程B和C也无法继续向前推进。

你会发现在T3时刻,这几个线程都没有任何进展,根本原因在于我们为解决多线程问题加互斥锁惊动了操作系统,而这类互斥锁是操作系统给我们实现的,那么解决线程安全问题一定要经过操作系统吗?

不是的,在硬件层面也可以解决线程安全问题,硬件层面当然是指CPU,或者说机器指令。

CPU中有特定的原子指令,实际上操作系统也是基于这些指令实现的互斥锁,既然操作系统能用这些指令,我们(用户态)也可以使用这些指令,基于此我们可以将上述代码进行简单改造:

int count = 0;void add() {int old_value;do {old_value = count;} while (!atomic_compare_exchange(&count, &old_value, old_value + 1));
}

此时add函数是线程安全的,我们也没有对其进行加锁,不管多少线程同时调用add函数得到count都是正确的,而该函数的执行完全不涉及操作系统 ,不需要操作系统来维护秩序,利用的就是CPU中的原子指令,CPU在硬件层面一样可以替我们维护秩序。

 

  资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

上述代码就是所谓lock-free的,不管操作系统怎样调度这三个线程,我们都能确保这三个线程中总有一个能继续向前推进 。

lock-free的系统看起来像这样:

对于这类系统不存在某个时间片下线程都无法推进的情况 ,换句话说就是lock-free程序保证至少有一个线程能继续向前推进。

可以看到,lock-free给出了比普通锁更优的保障。

但不能简单从代码是不是加锁或不加锁去判断代码是否lock-free ,回旋锁也是没有上述互斥锁的,也不经过操作系统,但回旋锁并不是lock-free的,如果你这样利用CPU中的原子操作修改add函数:

int count = 0;
int lock = 0;  // 回旋锁void add () {int expected = 0;while(!atomic_compare_exchange_weak(&lock, &expected, 1))expected = 0;count++;lock = 0;
}

这就是典型的回旋锁,然而如果某个线程持有回旋锁后被操作系统挂起那么其它线程开始无效的执行死循环,除了白白消耗CPU之外它们都无法继续向前推进,显而易见,如果此时系统负载较高那么此类程序的性能会变差。

既然现在你已经知道了lock-free我们再继续优化这段代码:

std::atomic<int> count;void add() {++count;
}

这段代码没有锁,也不需要用循环不断检测是否有其它线程修改count,不管操作系统如何调度这三个线程,它们都能在有限的操作数内执行完成 ,此时我们说该程序是wati-free的,wait-free系统运行起来像这样:

可以看到在任意时间片内,不管操作系统怎样调度,所有线程都能向前推进 。

wait-free比lock-free的要求更高更加严格,由于wait-free的程序总是能在有限的步骤内执行完成,因此实时性是最好的,适用于那些对实时性要求较高的场景,当然实现难度也要比lock-free更高。

值得注意的是,wait-free以及lock-free程序的实现通常不是那么简单。

 

http://www.ds6.com.cn/news/21346.html

相关文章:

  • wordpress输出某一分类的文章seo优化教程视频
  • 广元网站建设怎么做网络营销平台
  • 做餐厅网站的需求分析报告每日新闻摘抄10一30字
  • 网站建设主页文档网络营销的认知
  • 一个服务器可以建多少个网站中央常委成员名单
  • 国外优秀人像摄影网站花都网络推广seo公司
  • 淘宝网站建设的优点怎么在百度免费推广
  • 做信贷抢客户网站广州网站seo公司
  • 深圳网站建设公司 概况什么软件比百度搜索好
  • 郑州网站建设企业推荐中国站长之家网站
  • 重庆网站营销公司搜索引擎优化是什么意思
  • 用单位的服务器做网站软文营销方法有哪些
  • 大连科技公司建设网站百度安全中心
  • 步骤英文外贸网站优化公司
  • 旅游网站技术流程图网站设计的毕业论文
  • html做的网站自媒体平台收益排行榜
  • 怎样联系网站管理员河北百度seo关键词排名
  • 织梦怎么做中英文网站谷歌官网首页
  • 基于webform的网站开发优化大师有必要花钱吗
  • wordpress链接速度慢东莞网站优化
  • 短租网站开发上海搜索排名优化公司
  • 山西网站建设报价单淘宝推广工具
  • iis新建网站无法浏览产品推广平台排行榜
  • 南宁律师网站建设沈阳关键词自然排名
  • 李宁网站建设的可行性百度知道客服电话
  • 一般使用的分辨率显示密度是东莞网络优化服务商
  • 哪些网站可以做英语等级试题微信管理
  • 文艺风格wordpress主题重庆seo网站
  • 广西建设工程造价管理协会网站男生最喜欢的浏览器推荐
  • 免费网站你知道我的意思的热点新闻