确定一个对象何时不被任何其他线程使用而没有锁?

发布于 2024-08-16 05:38:07 字数 487 浏览 6 评论 0原文

我实现了一个高性能线程安全组件,没有使用锁语句,出于性能原因仅使用了 volatile 和 Interlocked 。

我在一个类中有易失性引用类型成员,其中包含线程安全实例。 该实例仅对于几个操作是线程安全的,而对于其他操作则不是。 因此,出于性能原因,在某些情况下,我更喜欢创建新实例而不是更新原始实例,而且它确实工作得更快,特别是因为我不使用任何锁定语句。

因此, volatile 成员可以随时替换为另一个实例, volatile 关键字保证了在多线程环境下不会出现任何问题。

这当然工作得很好,但唯一的问题是旧实例的垃圾收集。当测试我的组件的性能时,我发现它在已发布实例的垃圾收集上花费了太多时间。

现在我正在寻找一种回收旧实例的方法。问题是我不能在替换时只采用旧实例并重置它的状态,因为可能有另一个线程仍在使用该实例,并且我找不到一种方法(无锁)来保证没有人使用该实例不再了。

我如何保证没有线程使用没有锁定语句的旧实例? (首选易失性和互锁)

谢谢。

I implementing a high performance thread safe component, using no lock statements, only volatile and Interlocked are used for performance reasons.

I have volatile reference-type member in a class, that contains thread safe instance.
This instance is thread safe only for a couple of operations, and not for another.
Because of that and for performance reasons, in some cases i prefer creating new instance instead of updating the original, and it really working faster, especially because i dont using any lock statements.

So the volatile member can be replaced in any time to another instance, the volatile keyword ensures that there will not be any problem with that in multithreaded environment.

This of course working very well, but the only problem with that is the garbage collection of the old instances. When tested my component for performance, i found that it spending too much time in garbage collection the released instances.

Now i searching a way to recycle the old instances. The problem is that i can't just take the old instance when replacing and just reset it's state because there may be another threads that still using this instance and i can't found a way (without lock) that guaranties that noone using this instance anymore.

How can i guaranty that there is no thread that using the old instance without lock statements? (volatile and Interlocked are preferred)

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

撩心不撩汉 2024-08-23 05:38:07

您在这里尝试实现的内容看起来非常像引用计数(还记得 COM 吗?)。您可能可以通过递增/递减来做到这一点 - 只需在引用旁边保留一个引用计数器即可。

这种技术的唯一问题是它依赖于对象使用者来正确使用对象。这使得代码非常脆弱。

另一个问题是,据我所知,锁的主要性能问题不是锁本身,而是它所暗示的内存屏障。关键是对 volatile 变量的每次访问都会执行相同的操作。换句话说,我认为用易失性变量替换锁你不会获得任何东西

What you are trying to implement here looks so much like reference counting (remember COM?). You probably can do this with increments / decrements - just keep a reference counter right next to your reference.

The only problem with this technique is that it relies on the object consumers to be decent with object usage. This makes the code very fragile.

Another question is that AFAIK the main performance problem with locks is not the lock iteself but rather the memory barrier it implies. The point is that every acces to a volatile variable does the same. In other words I do not thnk you gained anything replacing locks with volatile variables

谈场末日恋爱 2024-08-23 05:38:07

问题是任何线程都可以将对对象的引用放入堆栈,然后用它做任何他们想做的事情。如果不使用整体锁,就无法防止非线程安全操作发生这种情况。

一般来说,您不应该尝试对抗 .NET 垃圾收集器 - 最好找出 GC 花费这么长时间的原因,并针对它进行优化(首先不要创建这么多实例,也许O(n^2) 操作创建大量实例?)而不是尝试以线程安全的方式重用实例。

The problem is that any thread can take a reference to object onto the stack, and then do whatever they want with it. There's no way of preventing this for the non-threadsafe operations without using an overall lock.

Generally, you shouldn't try to work against the .NET garbage collector - it'll be better to find out why GCs are taking so long, and optimize for that (don't create so many instances in the first place, maybe an O(n^2) operation creating lots of instances?) rather than trying to re-use instances in a thread-safe way.

拒绝两难 2024-08-23 05:38:07

您询问是否存在某种东西可以告诉您在多线程应用程序中对对象执行操作是否安全。这就是锁的定义。如果使用 .NET 提供的结构不够快,也许您应该考虑更改为运行速度更快的编译语言。

You are asking if something exists that will tell you if it is safe to do an operation on an object in a multi-threaded application. That is the definition of a lock. If using the structure that is provide by .NET is not fast enough, maybe you should consider changing to a complied language that will run faster.

思念绕指尖 2024-08-23 05:38:07

您可以使对象从死里复活,即当您的对象最终确定时,您实际上使它们再次复活。这样做的好处是,在它们生命周期的这一点上,不能有任何对它们的引用,否则它们一开始就不会适用于 Finalize。有关更多详细信息,请参阅本文中的“复活”一章。

现在,如果这真的能给你带来任何性能,或者是否值得这样做,我无法判断;-)

You could ressurect the object from the dead, i.e. when your objects are finalized you actually make them alive again. This has the benefit, that at this point in their lifecycle, there cannot be any reference to them, otherwise they would have never been applicable for finalize in the first place. For more details look for the "Ressurection" chapter in this article.

Now, if that really buys you any performance, or if it is worth doing it, I can't tell ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文