自旋锁-SpinLock(.NET 4.0+)
短时间锁定的情况下,自旋锁(spinlock)更快。(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用。所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待。对于多核CPU而言,减少了切换线程上下文的开销,从而提高了性能。)
以下是简单实例(并行执行10000次,每次想list中添加一项。执行完后准确的结果应该是10000):
foo1:使用系统的自旋锁。
foo4:不使用锁。结果必然是不正确的。
foo5:通过Interlocked实现自旋锁。
public class SpinLockDemo
{
int i = ;
List<int> li = new List<int>();
SpinLock sl = new SpinLock();
int signal = ; public void Execute()
{
foo1();
//li.ForEach((t) => { Console.WriteLine(t); });
Console.WriteLine("Li Count - Spinlock: "+li.Count);
li.Clear();
foo4();
Console.WriteLine("Li Count - Nolock: " + li.Count);
li.Clear();
foo5();
Console.WriteLine("Li Count - Customized Spinlock: " + li.Count); } public void foo1()
{
Parallel.For(, , r =>
{
bool gotLock = false; //释放成功
try
{
sl.Enter(ref gotLock); //进入锁
//Thread.Sleep(100);
if (i == )
{
i = ;
li.Add(r);
i = ;
}
}
finally
{
if (gotLock) sl.Exit(); //释放
} });
} public void foo4()
{
Parallel.For(, , r =>
{
if (i == )
{
i = ;
li.Add(r);
i = ;
}
});
} public void foo5()
{
Parallel.For(, , r =>
{
while (Interlocked.Exchange(ref signal, ) != )//加自旋锁
{}
li.Add(r);
Interlocked.Exchange(ref signal, ); //释放锁
}); } public void foo6()
{
//Console.WriteLine(i);
//Task.Run(new Action(foo2)).ContinueWith(new Action<Task>(t =>
//{
// Console.WriteLine("foo2 completed: " + i);
//}));
//Console.WriteLine(i);
//Task.Run(new Action(foo2)).ContinueWith(new Action<Task>(t =>
//{
// Console.WriteLine("foo3 completed: " + i);
//}));
//Console.WriteLine(i);
}
public void foo2()
{
bool lck = false;
sl.Enter(ref lck);
Thread.Sleep();
++i;
if (lck) sl.Exit();
} public void foo3()
{
bool lck = false;
sl.Enter(ref lck);
++i;
if (lck) sl.Exit();
}
}
结果如下:

自旋锁-SpinLock(.NET 4.0+)的更多相关文章
- 自旋锁spinlock
1 在单处理器上的实现 单核系统上,不存在严格的并发,因此对资源的共享主要是多个任务分时运行造成的. 只要在某一时段,停止任务切换,并且关中断(对于用户态应用程序,不大可能与中断处理程序抢临界区资源) ...
- 自旋锁spinlock解析
1 基础概念 自旋锁与相互排斥锁有点类似,仅仅是自旋锁不会引起调用者睡眠.假设自旋锁已经被别的运行单元保持.调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁."自旋"一词就 ...
- SpinLock 自旋锁, CAS操作(Compare & Set) ABA Problem
SpinLock 自旋锁 spinlock 用于CPU同步, 它的实现是基于CPU锁定数据总线的指令. 当某个CPU锁住数据总线后, 它读一个内存单元(spinlock_t)来判断这个spinlock ...
- SpinLock(自旋锁)
SpinLock(自旋锁) SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型 ...
- LiteOS:SpinLock自旋锁及LockDep死锁检测
摘要:除了多核的自旋锁机制,本文会介绍下LiteOS 5.0引入的LockDep死锁检测特性. 2020年12月发布的LiteOS 5.0推出了全新的内核,支持SMP多核调度功能.想学习SMP多核调度 ...
- Linux内核同步:自旋锁
linux内核--自旋锁的理解 自旋锁:如果内核配置为SMP系统,自旋锁就按SMP系统上的要求来实现真正的自旋等待,但是对于UP系统,自旋锁仅做抢占和中断操作,没有实现真正的“自旋”.如果配置了CON ...
- 【APUE】信号量、互斥体和自旋锁
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html http://blog.chinaunix.net/uid-205 ...
- 菜鸟nginx源代码剖析数据结构篇(十) 自旋锁ngx_spinlock
菜鸟nginx源代码剖析数据结构篇(十) 自旋锁ngx_spinlock Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.cs ...
- 多线程之美6一CAS与自旋锁
1.什么是CAS CAS 即 compare and swap 比较并交换, 涉及到三个参数,内存值V, 预期值A, 要更新为的值B, 拿着预期值A与内存值V比较,相等则符合预期,将内存值V更新为B, ...
随机推荐
- for 循环
#include <iostream> int main(){ ; ; val <= ; ++val) { sum += val; } std::cout << &quo ...
- Java NIO教程 Channel
Channel是一个连接到数据源的通道.程序不能直接用Channel中的数据,必须让Channel与BtyeBuffer交互数据,才能使用Buffer中的数据. 我们用FileChannel作为引子, ...
- Python-dict与set
dict(字典):用空间换取时间,占据空间大,但查询速度快,键值对(key:value),key唯一 d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} 由于一个k ...
- jQuery数组处理汇总
jQuery数组处理汇总 有段时间没写什么了, 打算把jquery中的比较常用的数组处理方法汇总一下 $.each(array, [callback])遍历,很常用 1 2 3 4 5 6 7 8 ...
- unity3d - new 不出的单例
可能习惯了写单例的朋友,或者常规的单例模式 会这样做 private static Single instance; public static Single Instance(){ if (inst ...
- Cable master poj1064(二分)
http://poj.org/problem?id=1064 题意:共有n段绳子,要求总共被分为k段.问在符合题意的前提下,每段长最大是多少? #include <iostream> #i ...
- 使用jquery form插件进行异步带文件的表单提交
引入form插件与jquery 的js文件后 获取表单的jq对象 然后.ajaxSubmit提交表单即可 实现添加品牌的异步表单提交 function addBarandImg(formId) { $ ...
- laravel 事件的使用案例
以下是我对事件使用的一些记录 创建事件 执行以下命令,执行完成后,会在 app\Events 下面出现一个 DeleteEvent.php 文件,事件就在次定义 php artisan make:ev ...
- margin设置为百分比的含义
<!DOCTYPE html> <html> <head> <title>magin为百分比</title> </head> & ...
- EhReport ,CReport改进版本,再次改进 ,V1.31
取消了xlgrid依赖,带齐了第三方包. 安装更加方便. For D7 下载源码