多线程 – 用于非阻塞多线程同步的无锁,无等待和等待自由算法

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

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

1)Lock-Free
2)Wait-Free
3)Wait-Freedom

我明白什么意思是无锁,但是当我们可以说某些同步算法是Wait-Free或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 }

你可以在这里找到RingBuffer单元:RingBuffer,CAS功能:FockFreePrimitives,测试程序:RingBufferFlowTest

最佳答案 (我正在回答这个问题,假设它是一个家庭作业问题,如果不是,请提供你所遇问题的更多细节)

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

点赞