goo*_*ate 22 c# c++ il interlocked interlocked-increment
该System.Threading.Interlocked对象允许加法(减法)和比较作为原子操作.似乎只是不做相等的CompareExchange以及作为原子比较的GreaterThan/LessThan将是非常有价值的.
Interlocked.GreaterThanIL 的假设特征还是CPU级功能?都?
缺少任何其他选项,是否可以用C++或直接IL代码创建这样的功能并将该功能公开给C#?
Ray*_*hen 45
你可以构建其他原子操作InterlockedCompareExchange.
public static bool InterlockedExchangeIfGreaterThan(ref int location, int comparison, int newValue)
{
int initialValue;
do
{
initialValue = location;
if (initialValue >= comparison) return false;
}
while (System.Threading.Interlocked.CompareExchange(ref location, newValue, initialValue) != initialValue);
return true;
}
Run Code Online (Sandbox Code Playgroud)
使用这些辅助方法,您不仅可以交换价值,还可以检测是否已替换价值。
用法如下所示:
int currentMin = 10; // can be changed from other thread at any moment
int potentialNewMin = 8;
if (InterlockedExtension.AssignIfNewValueSmaller(ref currentMin, potentialNewMin))
{
Console.WriteLine("New minimum: " + potentialNewMin);
}
Run Code Online (Sandbox Code Playgroud)
这里是方法:
public static class InterlockedExtension
{
public static bool AssignIfNewValueSmaller(ref int target, int newValue)
{
int snapshot;
bool stillLess;
do
{
snapshot = target;
stillLess = newValue < snapshot;
} while (stillLess && Interlocked.CompareExchange(ref target, newValue, snapshot) != snapshot);
return stillLess;
}
public static bool AssignIfNewValueBigger(ref int target, int newValue)
{
int snapshot;
bool stillMore;
do
{
snapshot = target;
stillMore = newValue > snapshot;
} while (stillMore && Interlocked.CompareExchange(ref target, newValue, snapshot) != snapshot);
return stillMore;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 3
更新我在这里发表的后一篇文章:我们找到了一种更好的方法,通过使用额外的锁对象来进行更大的比较。我们编写了许多单元测试来验证锁和 Interlocked 是否可以一起使用,但仅限于某些情况。
代码如何工作:Interlocked 使用内存屏障,读取或写入是原子的。需要同步锁来使大于比较成为原子操作。所以现在的规则是,在这个类中,没有这个同步锁,任何其他操作都不会写入该值。
我们从这个类中得到的是一个互锁的值,它可以非常快地读取,但写入需要更多的时间。在我们的应用程序中,读取速度大约快 2-4 倍。
这里的代码为视图:
请参阅此处:http ://files.thekieners.com/blogcontent/2012/ExchangeIfGreaterThan2.png
这里是复制和粘贴的代码:
public sealed class InterlockedValue
{
private long _myValue;
private readonly object _syncObj = new object();
public long ReadValue()
{
// reading of value (99.9% case in app) will not use lock-object,
// since this is too much overhead in our highly multithreaded app.
return Interlocked.Read(ref _myValue);
}
public bool SetValueIfGreaterThan(long value)
{
// sync Exchange access to _myValue, since a secure greater-than comparisons is needed
lock (_syncObj)
{
// greather than condition
if (value > Interlocked.Read(ref _myValue))
{
// now we can set value savely to _myValue.
Interlocked.Exchange(ref _myValue, value);
return true;
}
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7463 次 |
| 最近记录: |