C# 原子操作理解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C# 原子操作理解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2685字,纯文字阅读大概需要4分钟。
内容图文
![C# 原子操作理解](/upload/InfoBanner/zyjiaocheng/829/b49d63205cdf409eb6c0b5d1d2ec35c8.jpg)
C#内置提供的原子操作
- Interlocked.Increment:以原子操作的形式递增指定变量的值并存储结果。
- Interlocked.Decrement:以原子操作的形式递减指定变量的值并存储结果。
- Interlocked.Add:以原子操作的形式,添加两个整数并用两者的和替换第一个整数
问题:如果要进行原子的乘法、除法或者其他操作改怎么办,C#并没有内置提供相应的方法呀?
那我们先来大概理解一下原子操作的流程
以增加变量值为例
- 将实例变量添加到CPU寄存器中
- 将该变量的值进行增加
- 将该变量的增加后的值从CPU寄存器中还原到堆或栈中实例变量的值
可以看到如果是多核CPU在多线程环境下可能会导致在执行完步骤1,步骤2后当前线程失去时间片,其他线程读取改变量的值时就会读取到并未增加增加之前的值,所以就导致了数据的不一致。然而C#提供了上面三种原子操作来保证不出现这样的数据不一致,至于底层原理暂时不深究,我们来看看如何实现除这三种方法之外的操作。
进行原子的获取最大值操作
先放代码如下:
public static int Maximum(ref int target, int value)
{
//注意target前面加了 ref ,这样在方法外改变target的值将会影响到方法内的target值,
//即类似按引用传递
int currentVal = target;//使用currentVal局部变量来存储target值,target值的变更不会影响currentVal
int startVal = 0;
int desiredVal = 0;
do
{
startVal = currentVal; //记录本次迭代的起始值 1
desiredVal = Math.Max(startVal, value);//根据startVal和value计算最大值desiredVal 2
//如果target和startVal值一致则用desiredVal赋值给target,并将target原始值进行返回
//如果target和startVal值不相同则什么都不做,并将target的值进行返回
//target的值因为在别的线程进行操作时可能改变target的值,所以导致target值和startVal不一致
currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);// 3
} while (startVal != currentVal); // 4
//因为startVal记录的是开始时target的值,而currentVal记录的则是target最新值
//如果startVale和currentVal不一致则代表其他线程已经更改的target的值,所以需要重新迭代。
//重新迭代时currentVal代表的是target的最新值
//疑问:如果在 3 之后 4之前 target的值被其他线程更改怎么办?请大神帮忙
return desiredVal;
}
大致的逻辑可以参考注释进行理解,最主要的方法是通过currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal); 可以参考MSDN此方法的解释
其他操作
C# VIA CLR中给出了其他操作的模板,可以参考如下:
delegate int Morpher<TResult, TArgument>(int startValue, TArgument argument, out TResult morphResult);
static TResult Morph<TResult,TArgument>(ref int target,TArgument argument,Morpher<TResult,TArgument> morpher)
{
TResult morphResult;
int currentVal = target;
int startVal = 0;
int desiredVal = 0;
do
{
startVal = currentVal;
desiredVal = morpher(startVal, argument, out morphResult);
currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
} while (startVal != currentVal);
return morphResult;
}
可以通过委托定义自己想要的操作。乘法、除法等等。
大神写出的书就是牛,膜拜Jeffrey Richter
内容总结
以上是互联网集市为您收集整理的C# 原子操作理解全部内容,希望文章能够帮你解决C# 原子操作理解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。