仅使用原子操作的 C++/CLI 中的线程同步
我目前正在尝试使用 .net 中的 System::Threading::Interlocked 类仅使用原子操作来实现 C++ .net 中的线程同步。我对多线程完全没有经验,我正在尝试使用无锁线程同步。目前,我创建了一个名为设置的类,其中包含需要在线程之间共享的静态变量。然后我在其中创建了两个静态函数,一个用于设置静态数据成员,另一个用于读取它们。目前,这就是我的静态同步函数之一的样子。 我确实明白,如果两个以上的线程同时进入此函数,它们可能会永远陷入 while 循环中,但只有两个线程需要此函数,一个 GUI 线程和一个主线程将读取设置并将工作分派给工作线程。
//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);
};
我的问题是,您是否发现任何缺陷无法满足我的期望,或者整个同步想法是否存在缺陷?
I am currently trying to achieve thread synchronization in C++ .net using only atomic operations using the System::Threading::Interlocked class in .net. I'm not very experienced at all with multithreading and I'm trying to use lock-less thread synchronization. Currently I have created a class called settings that contains static variables that I need to share between threads. I then created two static functions in it, one for setting the static data members, and one for reading them. Currently this is what one of my static synchronization functions looks like. I do understand that if more than two threads enter this function at once, they could become stuck in the while loop forever, but only two threads will be needing this function, a GUI thread and the main thread that will read settings and dispatch work to worker threads.
//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);
};
My question is, do you see anything flawed that will not give me what I am expecting or is this whole idea for synchronization flawed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您能够确定多线程仅对最多两个线程是安全的,那么您就对多线程有敏锐的洞察力。不要让人们阻止您学习无锁技术。
您可以使用 InterlockedExchange 而不是增量,这将消除 >=2 个线程可能出现的死锁。然而,这个算法根本不是无锁编程,而是你正在实现你自己的锁。当然,这意味着您将遇到许多性能和正确性问题,这些问题已经由库锁定类(
Monitor
和朋友)解决了。这是
Interlocked::Exchange
< 的样子/a>You've got a good eye for multithreading if you were able to determine that this is safe for up to two threads only. Don't let people discourage you from studying lock-free techniques.
You could use
InterlockedExchange
instead of increment, which would remove the possible deadlock with >=2 threads. However, this algorithm is not lock-free programming at all, rather you are implementing your own lock. Of course this means you will run into many issues of performance and correctness that have already been solved by the library locking classes (Monitor
and friends).Here's what it would look like with
Interlocked::Exchange