当前位置: 首页 > 编程语言 > C#

非阻塞锁分享

时间:2023-04-11 11:29:05 C#

非阻塞锁我想开启一些新线程进行重复操作。但是当这样的操作已经在进行时,我想放弃当前的任务。在我的场景中,我只需要非常新鲜的数据——丢弃的数据不是问题。在MSDN中,我找到了Mutex类,但据我所知,它等待轮到它,阻塞当前线程。另外我想问你:.NET框架中有没有执行以下操作的东西:是否执行了某些方法M?如果是,则返回(并让我增加一些统计计数器)如果不是,则在新线程中启动方法M。您可能遇到过的lock(someObject)语句是Monitor.Enter和Monitor.Exit的语法糖。但是,如果您以这种更详细的方式使用Monitor,您还可以使用Monitor.TryEnter,它允许您检查您是否能够获取锁-从而检查其他人是否已经拥有它并正在执行代码。所以不是这个:varlockObject=newobject();lock(lockObject){//做一些事情}试试这个(选项1):int_alreadyBeingExecutedCounter;varlockObject=newobject();if(Monitor.TryEnter(lockObject)){//如果您在尝试获取锁时获得了锁,您只会在这里结束-否则您将永远不会执行此代码。//做一些事情//调用exit来释放锁Monitor.Exit(lockObject);}else{//没有得到锁-其他人正在执行上面的代码-所以我不需要做任何工作!互锁增量(ref_alreadyBeingExecutedCounter);}(您可能想尝试这个。.确保释放锁)或完全放弃显式锁并执行此操作(选项2)privateint_inUseCount;publicvoidMyMethod(){if(Interlocked.Increment(ref_inUseCount)==1){//做圆顶的东西}Interlocked.Decrement(ref_inUseCount);[编辑:回答你关于这个的问题]不-不要用它来锁定。创建一个私有范围的对象作为你的锁。否则你会遇到这个潜在的问题:publicvoidThreadACallsThis(){lock(_instance){//锁定我们的MyClassWithLockInside实例后,//做一些长时间运行的事情Thread.Sleep(6000);}}publicvoidThreadBCallsThis(){//如果线程B调用此方法,而线程A仍在上面的锁中,//此方法将阻塞,因为它试图获取同一对象上的锁//["this"insidetheclass=_instanceoutside]_instance.MethodThatTakesLock();在上面的例子中,一些外部代码设法通过锁定外部可访问的东西来打破我们类的内部锁定。最好创建一个你控制的私有对象,并且你的类之外的人不能访问,以避免这种问题;这包括不使用this或类型本身typeof(MyClassWithLockInside)进行锁定。一种选择是使用可重入哨兵:你可以定义一个int字段(初始化为0)并在进入方法时通过Interlocked.Increment更新它,只有为1时才继续。最后只执行Interlocked.Decrement。另一种选择:根据您的描述,您似乎有一个生产者-消费者-场景...对于这种情况,使用BlockingCollection之类的东西可能会有所帮助,因为它是线程安全的并且大部分是无锁的...另一种选择是使用ConcurrentQueue或ConcurrentStack...您可能会在以下站点上找到一些有用的信息(PDF也可以下载-我最近自己下载了)。您可能对高级线程暂停和恢复或中止章节不感兴趣。您应该使用Interlocked类基元操作-以获得最佳性能-因为您实际上不会使用系统级同步(任何“标准”基元都需要它,并且涉及系统调用开销)。//没有所有权的简单不可重入互斥锁,很容易重新设计以支持//这些功能(只需在获取锁后设置所有者(例如比较线程引用到Thread.CurrentThread),并检查匹配的身份,添加一个计数器forreentrancy)//bool不能使用,因为CompareExchangeprivateintlock不支持它;以上就是C#学习教程的全部内容:非阻塞锁共享,如果对大家有用还需要了解更多C#学习教程,希望大家多多关注—publicboolTryLock(){//if(Interlocked.Increment(ref_inUseCount)==1)//这种代码有问题-因为计数器可以在递增返回和//条件检查之间改变-递增是原子的,这个if-不是。//改用CompareExchange//检查是否0然后自动更改为1,返回原始值//如果线程成功占用锁,则返回TruereturnCompareExchange(reflock,1,0)==0;返回假;}publicboolRelease(){//如果锁被占用则返回真;false如果它已经空闲returnCompareExchange(reflock,0,1)==1;}网络收藏不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢