短时间锁定的情况下,自旋锁(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+)的更多相关文章

  1. 自旋锁spinlock

    1 在单处理器上的实现 单核系统上,不存在严格的并发,因此对资源的共享主要是多个任务分时运行造成的. 只要在某一时段,停止任务切换,并且关中断(对于用户态应用程序,不大可能与中断处理程序抢临界区资源) ...

  2. 自旋锁spinlock解析

    1 基础概念 自旋锁与相互排斥锁有点类似,仅仅是自旋锁不会引起调用者睡眠.假设自旋锁已经被别的运行单元保持.调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁."自旋"一词就 ...

  3. SpinLock 自旋锁, CAS操作(Compare & Set) ABA Problem

    SpinLock 自旋锁 spinlock 用于CPU同步, 它的实现是基于CPU锁定数据总线的指令. 当某个CPU锁住数据总线后, 它读一个内存单元(spinlock_t)来判断这个spinlock ...

  4. SpinLock(自旋锁)

    SpinLock(自旋锁) SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型 ...

  5. LiteOS:SpinLock自旋锁及LockDep死锁检测

    摘要:除了多核的自旋锁机制,本文会介绍下LiteOS 5.0引入的LockDep死锁检测特性. 2020年12月发布的LiteOS 5.0推出了全新的内核,支持SMP多核调度功能.想学习SMP多核调度 ...

  6. Linux内核同步:自旋锁

    linux内核--自旋锁的理解 自旋锁:如果内核配置为SMP系统,自旋锁就按SMP系统上的要求来实现真正的自旋等待,但是对于UP系统,自旋锁仅做抢占和中断操作,没有实现真正的“自旋”.如果配置了CON ...

  7. 【APUE】信号量、互斥体和自旋锁

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html http://blog.chinaunix.net/uid-205 ...

  8. 菜鸟nginx源代码剖析数据结构篇(十) 自旋锁ngx_spinlock

    菜鸟nginx源代码剖析数据结构篇(十) 自旋锁ngx_spinlock Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.cs ...

  9. 多线程之美6一CAS与自旋锁

    1.什么是CAS CAS 即 compare and swap 比较并交换, 涉及到三个参数,内存值V, 预期值A, 要更新为的值B, 拿着预期值A与内存值V比较,相等则符合预期,将内存值V更新为B, ...

随机推荐

  1. 循序渐进Python3(三) -- 3 -- 内置函数

    上一篇我们又介绍了26个Python内置函数.现回忆一下吧: 1.all 2.any 3.ascii 4.bin 5.bool 6.bytes 7.bytearray 8.callable 9.chr ...

  2. 2014 ACM/ICPC 北京邀请赛 部分 题解

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+C ...

  3. iOS界面的绘制和渲染

    界面的绘制和渲染 UIView是如何到显示的屏幕上的. 这件事要从RunLoop开始,RunLoop是一个60fps的回调,也就是说每16.7ms绘制一次屏幕,也就是我们需要在这个时间内完成view的 ...

  4. Linux C _exit函数与exit函数的联系与区别

    一.联系 1.功能上,_exit和exit函数都是让进程正常退出,即关闭进程所打开的文件描述符,释放已占用内存和其他资源. 二.区别 1._exit函数在头文件unistd.h中声明,而exit在头文 ...

  5. 防止刷新/后退引起的重复提交问题的Java Token代码,非Struts

    贴子转自http://hi.baidu.com/bobylou,转之前并没有验证文章里的方法是不是有效,估计原作者把它放到blog之前应该做过测试了吧. Struts本身有一套完善的防止重复提交表单的 ...

  6. 使用 BeanCopier 复制对象

    Cglib是一款比较底层的操作java字节码的框架. BeanCopier是一个工具类,可以用于Bean对象内容的复制. 复制Bean对象内容的方法有很多,比如自己手动get set ,或者使用Pro ...

  7. Vmware虚拟机克隆的网卡问题

    系统环境:red hat 6.4 在虚拟机上使用克隆后,克隆机没有eth0, 出现eth1并且出错No suitable device found: no device found for conne ...

  8. 今天想用jquery来实现div的拖放功能

    html5标签.拖放(Drag 和 drop)是 HTML5 标准的组成部分. 步骤一:首先设置标签可以被拖 draggable="true" 步骤二:选取被拖的标签,和要放置被拖 ...

  9. Sql 常见面试题

    SQL面试题(1) create table testtable1(id int IDENTITY,department varchar(12) ) select * from testtable1i ...

  10. [php-src]窥探Php内核中的变量

    内容均以php-5.6.14为例. 在看各种组合数据类型之前,有必要先熟悉下 Zend/zend_types.h 里面的自定义数据类型. #ifndef ZEND_TYPES_H // 防止多次 in ...