返回顶部
首页 > 资讯 > 前端开发 > VUE >怎么理解多核编程中的条件同步模式
  • 521
分享到

怎么理解多核编程中的条件同步模式

2024-04-02 19:04:59 521人浏览 独家记忆
摘要

本篇内容介绍了“怎么理解多核编程中的条件同步模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在多线程编程

本篇内容介绍了“怎么理解多核编程中的条件同步模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

多线程编程中,当对共享资源进行操作时,需要使用同步(通常是或原子操作)来进行保护,以避免数据竞争问题。不幸的是,同步操作的开销非常大,比如对一个整数变量进行加法操作,那么同步操作的开销是加法操作的上百倍以上。

有没有办法可以减少这种同步操作的开销呢?如果能设计出更快的锁或更快的原子操作来,那么这种开销自然就减少了。以目前的技术来看,最快速的原子操作耗时也是普通加法操作的上百倍,所以从这方面着手是非常困难的。

那么能不能从软件算法的角度来减少同步操作的开销呢?答案是当然可以,基本思想是减少使用同步的次数,比如原来要使用同步1000次,现在改为在满足一定条件下才使用同步,只需要10次,那么同步的开销平摊下来就被减少了100倍,效率大大提高了。下面先来看一个共享队列例子。

一个普通的共享队列通常都是使用锁来实现,当然也有用CAS原子操作来实现的,这里只讨论用锁来实现的共享队列。

在有锁保护的共享队列中,在队列的进队和出队操作时,通常都是使用锁来进行保护的,一个典型的使用锁保护的出队操作伪代码如下:

template class <T>        Locked_DeQueue(T &data)        {               Lock();               DeQueue(data);  //调用串行的出队操作               Unlock();        }

在使用上面的Locked_DeQueue()函数时,每调用一次,就会发生一次锁操作。事实上,并不是每次都需要加锁操作的,比如队列为空时,这时实际上是不需要进行出队操作的,完全可以采取的一定的方法避免锁操作,但是采用上面的Locked_DeQueue()函数无法避免锁操作,这就需要对上面的函数进行改进。

一种最容易想到的方面就是先判断队列是否为空,如果不为空才使用锁保护进行出队操作。代码如下:

template class <T>         Locked_DeQueue_a(T &data)         {                If ( !IsEmpty() )                {                       Lock();                       DeQueue(data);  //调用串行的出队操作                       Unlock();                }         }

上面的Locked_DeQueue_a()函数的一个关键之处是IsEmpty()函数必须不能使用锁操作,否则不仅没有减少同步开销,反而将同步开销增大了近一倍。

如何来使得IsEmtpy()函数不用锁操作呢,以数组实现的环行队列为例,在判断队列是否为空时,其基本方法是判断队首指针是否等于队尾指针。伪代码如下:

INT IsEmpty() {        Lock()         if ( 队首指针 == 队尾指针 )         {               Unlock();                return 1; //为空        }         else         {                   Unlock();                return 0; //非空        }  }

由于队首指针和队尾指针在进队或出队操作时会发生改变,因此在上面的IsEmpty()函数中,需要使用锁保护,那么如何去掉这层锁保护呢?

基本的方法是设一个标志变量EmptyFlag,在进队和出队操作中,当队列为空时,标志变量的值置为1,队列非空时,标志变量的值置为0。这样判断队列是否为空就可以通过EmptyFlag单个变量来进行,而单个变量的读写可以使用原子操作来实现,使得读操作和普通操作一样不存在同步操作。

下面是使用EmptyFlag变量实现的出队操作。

  1. template class <T> 

  2.        Locked_DeQueue_b(T &data) 

  3.  

  4.        {

  5.               if ( EmptyFlag ) 

  6.               { 

  7.                      return; 

  8.               } 

  9.               Lock(); 

  10.  

  11.               if ( !EmptyFlag )  //Lock()前, 其他线程可能修改了标志 

  12.  

  13.               { 

  14.                      DeQueue(data);  //调用串行的出队操作 

  15.  

  16.                   if ( 队首指针 == 队尾指针 ) 

  17.  

  18.                   { 

  19.                       //出队后,队列变空,使用原子操作将EmptyFlag置为1 

  20.  

  21.                       AtomicIncrement(&EmptyFlag); 

  22.                   } 

  23.               } 

  24.  

  25.               Unlock(); 

  26.        } 

队列的是否为空函数可以使用下面的完全不需要同步的实现。

INT IsEmpty()         {                return EmptyFlag;         }

从Locked_DeQueue_b()函数的实现可以看出,如果队列本来为空的情况下,它只判断一个EmptyFlag就返回了,不会调用锁操作,减少了同步使用的次数,并且在IsEmpty()函数中,根本不需要使用同步,这对于那些需要频繁判断队列是否为空的使用场景,有很好的效果。

比 如对于动态任务调度,假设使用普通的有锁的共享队列。当一个线程私有队列为空时,需要去偷取其他线程的共享队列中的任务,如果偷取的队列为空则发生了一次 锁操作,此时需要再偷另外一个队列的任务,如果这个队列仍然为空则又要一次锁操作,一次获取任务的操作中将可能出现多次加锁解锁的情况。通过上面讲的条件 同步方法就可以在偷取取一个任务时,只要一次锁操作就可以实现。

上面讲的条件同步模式非常适应于具有状态机性质的场合,只有在发生状态切换(例如队列中空或非空的状态的切换)时才使用同步,通过对状态变量(例如EmptyFlag)的操作来替代其他非状态变量(例如队首指针和队尾指针)的操作,减少同步的使用。

“怎么理解多核编程中的条件同步模式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么理解多核编程中的条件同步模式

本文链接: https://lsjlt.com/news/86400.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么理解多核编程中的条件同步模式
    本篇内容介绍了“怎么理解多核编程中的条件同步模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在多线程编程...
    99+
    2024-04-02
  • 怎么理解多核编程中的线程分组竞争模式
    这篇文章主要介绍“怎么理解多核编程中的线程分组竞争模式”,在日常操作中,相信很多人在怎么理解多核编程中的线程分组竞争模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解...
    99+
    2024-04-02
  • 怎么理解多核编程中的负载平衡
    本篇内容主要讲解“怎么理解多核编程中的负载平衡”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解多核编程中的负载平衡”吧!多核CPU中,要很好地发挥出多个C...
    99+
    2024-04-02
  • 基于事件的异步编程模式EMP如何理解
    基于事件的异步编程模式EMP如何理解,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。.NET1.0中基于IAsyncResult设计模式的异步编程模型(APM),它使用Sys...
    99+
    2023-06-17
  • Node.js 事件循环中的异步编程模式与反模式
    ...
    99+
    2024-04-02
  • 多核编程中的线程随机竞争模式的概率分析
    这篇文章主要讲解了“多核编程中的线程随机竞争模式的概率分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“多核编程中的线程随机竞争模式的概率分析”吧!并 不是...
    99+
    2024-04-02
  • C#中的异步编程模式是什么
    在C#中,异步编程模式是通过async和await关键字来实现的。使用这种方式可以将耗时的操作(例如网络请求、文件操作等)放在一个单...
    99+
    2024-04-03
    C#
  • Java多线程中不同条件下编写生产消费者模型的示例分析
    这篇文章主要为大家展示了“Java多线程中不同条件下编写生产消费者模型的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java多线程中不同条件下编写生产消费者模型的示例分析”这篇文章吧。...
    99+
    2023-05-30
    java
  • c语言多线程同步机制怎么理解
    C语言多线程同步机制是指在多线程程序中,通过一些机制来保证多个线程之间的协调执行,避免出现竞争条件和死锁等问题。常见的多线程同步机制...
    99+
    2023-09-14
    c语言
  • Java中多线程同步的原理是什么
    Java中多线程同步的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、线程的先来后到我们来举一个Dirty的例子:某餐厅的卫生间很小,几乎只能容纳一个人如厕。为了保...
    99+
    2023-06-17
  • .NET2.0版本中基于事件的异步编程模式(EAP)
    一、引言 APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进度报告的功能,对于有界面的应用程序来说...
    99+
    2024-04-02
  • 如何理解CSS编程中的怪异模式
    今天就跟大家聊聊有关如何理解CSS编程中的怪异模式,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。怪异模式盒模型今天学习了一下css3的box-siz...
    99+
    2024-04-02
  • Java怎么实现多线程中的静态代理模式
    这篇文章将为大家详细讲解有关Java怎么实现多线程中的静态代理模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样...
    99+
    2023-06-15
  • C#开发中如何处理并发编程和多线程同步问题及解决方法
    C#开发中如何处理并发编程和多线程同步问题及解决方法在如今的软件开发领域中,并发编程已经成为一种常见的需求。在许多应用程序中,我们需要同时处理多个任务,而多线程是实现这个目标的一种常见方式。然而,处理并发编程和多线程同步问题并不容易。本文将...
    99+
    2023-10-22
    并发编程 解决方法 多线程同步
  • 怎么在java中实现多线程的互斥与同步
    这篇文章将为大家详细讲解有关怎么在java中实现多线程的互斥与同步,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、线程互斥与同步互斥:指的是多个线程不能同时访问共享变量同步:指的是多个线程...
    99+
    2023-06-15
  • 怎么理解Redis中的哨兵模式
    本篇内容介绍了“怎么理解Redis中的哨兵模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Redis 主...
    99+
    2024-04-02
  • Java中的响应式编程:如何利用异步方式处理不同的数据类型?
    响应式编程是一种处理异步和事件驱动程序的编程范式,它可以极大地提高程序的性能和可扩展性。Java中的响应式编程是一种基于流的编程方式,可以让我们更加高效地处理不同类型的数据。在本文中,我们将介绍Java中的响应式编程及其使用。 一、什么是...
    99+
    2023-10-21
    数据类型 响应 异步编程
  • 怎么理解C++11 中的线程及锁和条件变量
    今天就跟大家聊聊有关怎么理解C++11 中的线程及锁和条件变量,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。线程类std::thread代表一个可执行线程,使用时必须包含头文件<...
    99+
    2023-06-17
  • 详解R语言中的多项式回归、局部回归、核平滑和平滑样条回归模型
    目录多项式回归局部回归样条平滑在标准线性模型中,我们假设 。当线性假设无法满足时,可以考虑使用其他方法。 多项式回归 扩展可能是假设某些多项式函数, 同样,在标准线性模型...
    99+
    2024-04-02
  • 怎么深入理解Java设计模式中的访问者模式
    怎么深入理解Java设计模式中的访问者模式,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、什么是访问者模式定义:表示一个作用于其对象结构中的各元素的操作,它使你可以在不改变各...
    99+
    2023-06-25
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作