.net - 仅使用原子操作的 C++/CLI 中的线程同步

标签 .net multithreading synchronization c++-cli atomic

我目前正在尝试使用 .net 中的 System::Threading::Interlocked 类仅使用原子操作在 C++ .net 中实现线程同步。我对多线程完全没有经验,我正在尝试使用无锁线程同步。目前,我创建了一个名为 settings 的类,其中包含我需要在线程之间共享的静态变量。然后我在其中创建了两个静态函数,一个用于设置静态数据成员,一个用于读取它们。目前,这就是我的静态同步功能之一。 我明白如果两个以上的线程同时进入这个函数,它们可能会永远卡在while循环中,但是只有两个线程需要这个函数 ,一个 GUI 线程和主线程,它将读取设置并将工作分派(dispatch)给工作线程。


//object is handle to instance of settings class that also contains non-static
//members that will contain each threads copy of the data.
void Settings::SetStaticVariables(Settings ^object)
{
    int returnvalue;

    //canchange variable is a static integer of the class "Settings"
    returnvalue = Threading::Interlocked::Increment(Settings::canchange);
    if(returnvalue > 1)
    {
        while(Settings::canchange > 1)
        {
            //perhaps eventually I will find an alternative to telling the thread
            //to sleep for a defined amount of time, maybe when I learn how to use events
            //for now this will do, speed is not very important for this data sync as 
            //it does not occure often
            Threading::Thread::Sleep(50);
        }
    }
    //data synchronization of static members here

    //decrement allowing waiting threads to exit while loop
    Threading::Interlocked::Decrement(Settings::canchange);
};

我的问题是,您是否看到任何无法满足我期望的缺陷,或者同步的整个想法是否存在缺陷?

最佳答案

如果您能够确定这对于最多两个线程是安全的,那么您对多线程有很好的了解。不要让人们阻止你学习无锁技术。

您可以使用 InterlockedExchange而不是增量,这将消除 >=2 线程的可能死锁。但是,该算法根本不是无锁编程,而是您正在实现自己的锁。当然,这意味着您将遇到许多已由库锁定类(Monitor 和 friend )解决的性能和正确性问题。

这是 Interlocked::Exchange 的样子

// try to acquire lock
while (0 != Interlocked::Exchange(Settings::canchange, 1))
{
   Thread::Sleep(50);
}

MemoryBarrierAcquire();

// update shared variables

// flush cached writes
MemoryBarrierRelease();
// unlock
Settings::canchange = 0;

关于.net - 仅使用原子操作的 C++/CLI 中的线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4882271/

相关文章:

c++ - 如何从外语线程调用python函数(C++)

java - 有选择地实现同步以促进最大并发性

java - java中如何让两架飞机同步降落在两条不同的跑道上?

c# - 如何使用 .NET 4.5 异步和流式处理将 Blob 数据存储在 Redis 上?

c# - Reflection.Emit - IL - 对象上的调用方法

c# - Int32.Parse 与 Single.Parse - ("1,234") 和 ("1,2,3,4")。为什么 int 和浮点类型以不同方式解析分隔符?

java - Java异步文件写入PipedOutputStream/PipedInputStream(或Reader/Writer)与BlockingQueue的异同

java - SwingWorker线程即使任务完成也没有关闭?

core-data - 今日 iCloud + 核心数据(2015 年 7 月 10 日)

c# - 应用程序起点上的 StackOverFlow