代码之家  ›  专栏  ›  技术社区  ›  Eric

如何使用系统::线程::联锁::从C++到CLI的静态变量增量?

  •  1
  • Eric  · 技术社区  · 16 年前

    我希望在垃圾收集类中保留一个静态计数器,并使用interlocked::increment对其进行递增。C++/CLI语法是做什么的?

    我一直在尝试以下的变化,但到目前为止还没有运气:

    ref class Foo
    {
       static __int64 _counter;
    
       __int64 Next()
       {
          return System::Threading::Interlocked::Increment( &_counter );
       }
    
    };
    
    3 回复  |  直到 8 年前
        1
  •  5
  •   McKenzieG1    16 年前

    你需要使用 tracking reference 对你 _int64 值,使用%跟踪引用表示法:

    ref class Bar
    {
        static __int64 _counter;
    
        __int64 Next()
        {
            __int64 %trackRefCounter = _counter;
            return System::Threading::Interlocked::Increment(trackRefCounter);
        }
    };
    
        2
  •  2
  •   Ben Voigt    13 年前

    只需删除操作员的地址:

    return System::Threading::Interlocked::Increment( _counter );
    

    在C++/CLI中,像C++一样,没有经过引用的特殊符号。

    或者可以使用本机函数, InterlockedIncrement64 ( #include <windows.h> )

    return ::InterlockedIncrement64(&_counter);
    
        3
  •  0
  •   Glenn Slayden    8 年前

    建议使用 本机函数/宏 (即 InterlockedExchangePointer 等。还有很多我不知道的很酷的,比如 InterlockedXor64 )因为这样做会导致一个内在的(至少在默认编译器设置下)被放到托管的 C++/CLI 功能。当发生这种情况时,您的整个函数将被编译为本机函数。

    以及 Interlocked::* 也很好,因为你不必 pin_ptr 如果目标位于GC对象中。然而,正如本页所指出的,找到正确的咒语让它工作可能是一种真正的痛苦,特别是当你想交换(即)本地指针本身时。以下是如何:

    int i1 = 1, i2 = 2;
    
    int *pi1 = &i1, *pi2 = &i2, *pi3;
    
    pi3 = (int*)Interlocked::Exchange((IntPtr%)pi1, IntPtr(pi2)).ToPointer();
    

    我证实这确实有效,尽管缺乏令人怀疑的地址记录令人不安( & ) pi1 指针。但这是有意义的,当您考虑它时,因为如果目标在一个GC主机中移动,您将不希望像往常一样 ** 抓住 & 指针本身的(本机)地址。