Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 非阻塞多线程同步的无锁、无等待和无等待算法_Multithreading_Delphi_Synchronization_Delphi 2007 - Fatal编程技术网

Multithreading 非阻塞多线程同步的无锁、无等待和无等待算法

Multithreading 非阻塞多线程同步的无锁、无等待和无等待算法,multithreading,delphi,synchronization,delphi-2007,Multithreading,Delphi,Synchronization,Delphi 2007,在多线程编程中,我们可以找到两个或多个线程/任务之间数据传输同步的不同术语 确切地说,我们可以说某些算法是: 1)Lock-Free 2)Wait-Free 3)Wait-Freedom 我理解什么是无锁,但当我们可以说某些同步算法是无等待还是无等待时? 我为多线程同步编写了一些代码(环形缓冲区),它使用无锁方法,但: 算法预测此例程的最大执行时间 在开始时调用此例程的线程设置唯一引用(在此例程内部) 调用同一例程的其他线程检查此引用,如果设置了此引用,则计算第一个相关线程的CPU周期计数(测

在多线程编程中,我们可以找到两个或多个线程/任务之间数据传输同步的不同术语

确切地说,我们可以说某些算法是:

1)Lock-Free
2)Wait-Free
3)Wait-Freedom
我理解什么是无锁,但当我们可以说某些同步算法是无等待还是无等待时? 我为多线程同步编写了一些代码(环形缓冲区),它使用无锁方法,但:

  • 算法预测此例程的最大执行时间
  • 在开始时调用此例程的线程设置唯一引用(在此例程内部)
  • 调用同一例程的其他线程检查此引用,如果设置了此引用,则计算第一个相关线程的CPU周期计数(测量时间)。如果那个时间长了,就中断当前涉及线程的工作,并覆盖他的工作
  • 由于任务调度程序中断而未完成作业的线程(在结束时被重置)检查引用(如果不属于他),再次重复该作业
  • 因此,该算法不是真正的无锁算法,但是没有内存锁在使用中,其他相关线程可以等待(或不等待)一定的时间,然后再跳过休眠线程的作业

    添加了RingBuffer.InsertLeft函数:

    function TgjRingBuffer.InsertLeft(const link: pointer): integer;
    var
      AtStartReference: cardinal;
      CPUTimeStamp    : int64;
      CurrentLeft     : pointer;
      CurrentReference: cardinal;
      NewLeft         : PReferencedPtr;
      Reference       : cardinal;
    label
      TryAgain;
    begin
      Reference := GetThreadId + 1;                 //Reference.bit0 := 1
      with rbRingBuffer^ do begin
    TryAgain:
        //Set Left.Reference with respect to all other cores :)
        CPUTimeStamp := GetCPUTimeStamp + LoopTicks;
        AtStartReference := Left.Reference OR 1;    //Reference.bit0 := 1
        repeat
          CurrentReference := Left.Reference;
        until (CurrentReference AND 1 = 0)or (GetCPUTimeStamp - CPUTimeStamp > 0);
        //No threads present in ring buffer or current thread timeout
        if ((CurrentReference AND 1 <> 0) and (AtStartReference <> CurrentReference)) or
          not CAS32(CurrentReference, Reference, Left.Reference) then
          goto TryAgain;
        //Calculate RingBuffer NewLeft address
        CurrentLeft := Left.Link;
        NewLeft := pointer(cardinal(CurrentLeft) - SizeOf(TReferencedPtr));
        if cardinal(NewLeft) < cardinal(@Buffer) then
          NewLeft := EndBuffer;
        //Calcolate distance
        result := integer(Right.Link) - Integer(NewLeft);
        //Check buffer full
        if result = 0 then                  //Clear Reference if task still own reference
          if CAS32(Reference, 0, Left.Reference) then
            Exit else
            goto TryAgain;
        //Set NewLeft.Reference
        NewLeft^.Reference := Reference;
        SFence;
        //Try to set link and try to exchange NewLeft and clear Reference if task own reference
        if (Reference <> Left.Reference) or
          not CAS64(NewLeft^.Link, Reference, link, Reference, NewLeft^) or
          not CAS64(CurrentLeft, Reference, NewLeft, 0, Left) then
          goto TryAgain;
        //Calcolate result
        if result < 0 then
          result := Length - integer(cardinal(not Result) div SizeOf(TReferencedPtr)) else
          result := cardinal(result) div SizeOf(TReferencedPtr);
      end; //with
    end; { TgjRingBuffer.InsertLeft }
    
    函数TgjRingBuffer.InsertLeft(const-link:pointer):整数;
    变量
    AtStartReference:红衣主教;
    CPUTimeStamp:int64;
    CurrentLeft:指针;
    当前参考:红衣主教;
    新左派:首选DPTR;
    参考:红衣主教;
    标签
    特里亚根;
    开始
    引用:=GetThreadId+1//Reference.bit0:=1
    使用rbRingBuffer ^do开始
    TryAgain:
    //向左设置。相对于所有其他核心的参考:)
    CPUTimeStamp:=GetCPUTimeStamp+LoopTicks;
    AtStartReference:=左参考或1//Reference.bit0:=1
    重复
    CurrentReference:=左。参考;
    直到(CurrentReference和1=0)或(GetCPUTimeStamp-CPUTimeStamp>0);
    //环缓冲区中不存在线程或当前线程超时
    如果((CurrentReference和1 0)和(AtStartReference CurrentReference))或
    不是CAS32(CurrentReference,Reference,Left.Reference)那么
    goto TryAgain;
    //计算RingBuffer NewLeft地址
    CurrentLeft:=左.链接;
    NewLeft:=指针(基数(CurrentLeft)-SizeOf(TReferencedPtr));
    如果基数(NewLeft)
    您可以在这里找到环缓冲区单元:,CAS函数:,以及测试程序:

    (我回答这个问题的前提是假设它是一个家庭作业问题,如果不是,请提供您遇到的问题的更多细节)


    你应该开始阅读维基百科上的文章。这提供了一些很好的背景信息和你提到的术语的一些定义。

    我将对此进行研究,尽管我没有经过正式培训,也不在乎这是否是家庭作业,因为op要求的是确定“什么算法”,对我来说(海报框定了工作)是“无等待状态”涉及执行元组的编程——这正是系统编程必须解决的问题

  • 1) 算法预测最大值 此例程的执行时间 必须确定数据集大小以及应用于数据集的数据结构的“O”。这可能涉及到“退化案例”(人们没有计划的事情),在不可预料的时刻造成破坏。因此,在没有更多细节的情况下,我们选择了一种良好的“一般案例”方法,这种方法已知故障模式,并且能够在没有“周末破坏”的情况下恢复。Robert Sedgewick拥有我能够获得任何进展的最先进的作品——这部作品非常清晰地描述了您提出的问题

  • 2) 调用此例程的线程 开始设置唯一引用,什么 我的意思是这是例行程序的一部分
  • 这里有一些语言障碍,但我猜您要问的是,代码执行路径(指令序列)以对其数据集的“唯一”引用开始-因此,唯一引用正好意味着这一点-所以我们只是在标准词典中重新阅读它的定义。(无意陈词滥调,这正是我在这里看到的)

  • 3) 正在调用的其他线程 同样的例行检查 参考和if设置为小于计数 的CPU滴答计数(测量时间) 第一个涉及的线程。如果那时候 就是长时间中断电流 相关线程的工作和 他失去了工作
  • 参考计数。好好学习-只需继续阅读和编码。解决它。中断过期的线程完成充满了看不见的故障模式。老实说,真正的调度(线程或进程)只能在设计用于容纳该任务的硬件中正确完成。您的“组装优化”帖子可以在一定程度上实现这一点。我建议研究“AVL”零页算法。在某一点上,处理器和