获取 Singleton 类 Instance Multithread [英] Aquire Singleton class Instance Multithread

查看:20
本文介绍了获取 Singleton 类 Instance Multithread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要获得具有单例模式的类的实例,我想使用以下函数:

To get the instance of the class with Singleton pattern, I want use the following function:

这是草图

interface

uses SyncObjs;

type
  TMCriticalSection = class(TCriticalSection)
  private
    Dummy : array [0..95] of Byte;
  end;

var
  InstanceNumber : Integer;
  AObject: TObject;
  CriticalSection: TMCriticalSection;

function getInstance: TObject;

implementation

uses Windows;

function getInstance: TObject;
begin
   //I Want somehow use InterlockedCompareExchange instead of CriticalSession, for example

   if InterlockedCompareExchange(InstanceNumber, 1, 0) > 0 then
   begin
     Result := AObject;
   end
   else
   begin
      CriticalSection.Enter;
      try
        AObject := TObject.Create;
      finally
        CriticalSection.Leave;
      end;
      InterlockedIncrement(InstanceNumber);
      Result := AObject
   end;
end;

initialization
  CriticalSection := TMCriticalSection.Create;
  InstanceNumber := 0;

finalization;
  CriticalSection.Free;

end.

三个问题:

1- 这种设计是线程安全的吗?尤其是带有 InterlockedExchange 的部分.
2- 如何使用 InterlockedCompareExchange?有可能做我正在尝试的事情吗?
3- 这种设计是否比包含关键部分范围内的所有代码更好?

1- Is this design Thread Safe? Especially the with InterlockedExchange Part.
2- How to use the InterlockedCompareExchange? Is it possible to do what i'm trying?
3- Is this design better than involve all code within the critical section scope?

备注:我的对象是线程安全的,只有我需要序列化的构造!
这不是内部代码,只是重要的部分,我的意思是 getInstance 函数.

需要使用某种单例对象.
如果 InstanceNumber 的值为零,有什么方法可以使用 InterlockedCompareExchange 进行比较?

1 - 仅当为 0 时才创建对象,否则返回实例.
2 - 当值为 0 时:进入临界区.创建对象.离开临界区.
3 - 这样做会更好,而不是涉及关键部分范围内的所有代码?

I NEED to use some kind of singleton object.
Is there any way to use InterlockedCompareExchange to compare if the value of InstanceNumber is zero?
And
1 - Create the object only when is 0, otherwise, return the instance.
2 - When the value is 0: Enter in the critical section. Create the object. Leave critical section.
3 - Would be better to do this way, instead of involve all code within the critical section scope?

推荐答案

您的设计不起作用,即使不了解 InterlockedCompareExchange 的作用,也可以看出这一点.事实上,不管 InterlockedCompareExchange 的含义如何,你的代码都被破坏了.

Your design does not work and this can be seen even without any understanding of what InterlockedCompareExchange does. In fact, irrespective of the meaning of InterlockedCompareExchange, your code is broken.

要看到这一点,请考虑两个线程同时到达 getInstance 中的 if 语句.让我们考虑他们采取哪些分支的三个选项:

To see this, consider two threads arriving at the if statement in getInstance at the same time. Let's consider the three options for which branches they take:

  1. 他们都选择了第二个分支.然后您创建两个实例,您的代码不再实现单例.
  2. 他们都选择了第一个分支.那么你永远不会创建实例.
  3. 一个选择第一个,另一个选择第二个.但是由于第一个分支中没有锁,因此采用该路由的线程可以在其他线程写入之前读取 AObject.

我个人会使用 double-如果我必须实现您的 getInstance 函数,请检查锁定.

Personally I'd use double-checked locking if I had to implement your getInstance function.

这篇关于获取 Singleton 类 Instance Multithread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆