减lessprimefaces计数器 – 但<只>在一个条件下

我想要了解这方面的一些东西:

inline void DecrementPendingWorkItems() { if(this->pendingWorkItems != 0) //make sure we don't underflow and get a very high number { ::InterlockedDecrement(&this->pendingWorkItems); } } 

我怎么能做到这一点,使两个操作是primefaces的块,而不使用锁?

您可以只检查InterlockedDecrement()的结果,如果碰巧是否定的(或<= 0,如果这是更可取的)通过调用InterlockedIncrement()撤销递减。 在其他适当的代码,应该是很好的。

最简单的解决方案就是在整个部分使用一个互斥体(以及对this->pendingWorkItems所有其他访问)。 如果由于某种原因,这是不可接受的,那么你可能需要比较和交换:

 void decrementPendingWorkItems() { int count = std::atomic_load( &pendingWorkItems ); while ( count != 0 && ! std::atomic_compare_exchange_weak( &pendingWorkItems, &count, count - 1 ) ) { } } 

(这假设pendingWorkItems类型为std::atomic_int 。)

有一种叫做“SpinLock”的东西。 这是一个非常轻量级的同步。

这是这个想法:

 // // This lock should be used only when operation with protected resource // is very short like several comparisons or assignments. // class SpinLock { public: __forceinline SpinLock() { body = 0; } __forceinline void Lock() { int spin = 15; for(;;) { if(!InterlockedExchange(&body, 1)) break; if(--spin == 0) { Sleep(10); spin = 29; } } } __forceinline void Unlock() { InterlockedExchange(&body, 0); } protected: long body; }; 

样本中的实际数字并不重要。 这个锁是非常有效的。

您可以在循环中使用InterlockedCompareExchange

  inline void DecrementPendingWorkItems() { LONG old_items = this->pendingWorkingItems; LONG items; while ((items = old_items) > 0) { old_items = ::InterlockedCompareExchange(&this->pendingWorkItems, items-1, items); if (old_items == items) break; } } 

InterlockedCompareExchange函数做的是:

  if pendingWorkItems matches items, then set the value to items-1 and return items else return pendingWorkItems 

这是自动完成的,也被称为比较和交换

使用原子CAS。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560(v=vs.85).aspx

你可以让它自由锁定,但不能等待自由。

正如基里尔所说,这与你的情况下的自旋锁相似。

我认为这是你所需要的,但我建议在继续使用之前考虑所有的可能性,因为我还没有测试过它:

 inline bool InterlockedSetIfEqual(volatile LONG* dest, LONG exchange, LONG comperand) { return comperand == ::InterlockedCompareExchange(dest, exchange, comperand); } inline bool InterlockedDecrementNotZero(volatile LONG* ptr) { LONG comperand; LONG exchange; do { comperand = *ptr; exchange = comperand-1; if (comperand <= 0) { return false; } } while (!InterlockedSetIfEqual(ptr,exchange,comperand)); return true; } 

还有一个问题,为什么你的工作项目应该低于零。 你应该确保增量的数量与减少的数量相匹配,并且都可以。 如果违反了这个约束,我可能会添加一个断言或异常。