|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
pseudo spin-lock design helpI wrote some code and it seems ok to me but since it is going into a high-use production environment, I wanted some peer-review if possible. Basically, I wanted a way to know if an object is being "reset" and only allow one thread to reset it at any one time. This is what I came up with: Private _lockResetSync As Object = New Object() Private _lockResetWaitEvent As ManualResetEvent = New ManualResetEvent(False) Private _IsResetting As Boolean = False Public Sub Reset(ByVal cmd As Object) Dim _ThisThreadIsResetting As Boolean = False While Not _ThisThreadIsResetting ' pseudo-spin-lock for thread safety If _IsResetting Then _lockResetWaitEvent.WaitOne() Exit Sub End If SyncLock _lockResetSync If Not _IsResetting Then _lockResetWaitEvent.Reset() _IsResetting = True _ThisThreadIsResetting = True End If End SyncLock End While Try ' !! Do time-consuming thread-safe stuff here Finally _IsResetting = False _lockResetWaitEvent.Set() End Try End Sub Public ReadOnly Property IsResetting() As Boolean Get Return _IsResetting End Get End Property I feel if two threads came into Reset() at the same clock-tick (hehe), this would still work correctly. Also, external objects would know what is going on. Will this work and if not, what is a better way to do this? Thank you, Michael mpa***@htxml.com wrote:
>I wrote some code and it seems ok to me but since it is going into a I found your code tortuous to follow. If you want peer-review you'll>high-use production environment, I wanted some peer-review if possible. need to document it! i.e. write at the top what the specification is for your code. Anyway, here's my attempt at a simpler alternative. The specification is: we have a global variable called "state", which is normally 0 (unset) or 1 (set). It also has a special state 1 (resetting). Only one thread is allowed to be resetting at any one time, and the resetting process may be lengthy. Private state As Integer = 1 Public Sub reset() While Interlocked.CompareExchange(state, 2, 1) <> 1 End While ' ... Interlocked.CompareExchange(state, 0, 2) End Sub Nots on the code: the initial While loop will keep going until we succeed in being the unique thread who shifts it from 1 to 2. Then the "..." body proceeds. Within this body, we are guaranteed that we are the only thread running this body while in state 2. (note: this guarantee depends on the fact that no one changes the state except through our own carefully controlled methods). Finally we complete our resetting by putting it back to 0. This final CompareExchange is guaranteed to succeed. That's because no one else was able to shift from state 2 to anything. (but we should probably but a Debug.Assert there). Note: it's possible to put a Wait inside the initial while loop, but not needed. Could even use a Sleep. -- Lucian Lucian Wischik <lu***@wischik.com> wrote:
>0 (unset) or 1 (set). It also has a special state 1 (resetting). I meant "2 (resetting)" obviously!-- Lucian Your "_IsResetting" boolean, is going to cause you major, major, major
trouble. It needs to be marked as volatile (which VB.Net doesn't support, IIRC) or you need to access it using either the Interlocked operations, the Thread.VolatileRead/VolatileWrite constructs, or with (don't do this!) a MemoryBarrier. I didn't really look through the code in any more depth than that. Looking through your code, I would strongly suggest you go pull down Jeff Richter's Power Threading library from the Wintellect site, and use his threading constructs. They're already debugged, well documented, and easy to use. Writing this level of complexity yourself, when you're not an expert (and your use of the boolean member says you're not yet an expert), is going to be an excercise in frustration. It's also going to always (!!) have subtle bugs in it. These bugs are also a nightmare to track down and debug. For an example of the type of debugging you'll be stuck doing: http://www.coversant.net/Default.aspx?tabid=88&EntryID=28 -- Show quoteHide quoteChris Mullilns, MCSD.NET, MCPD:Enterprise http://www.coversant.net/blogs/cmullins <mpa***@htxml.com> wrote in message news:1166733461.417765.310300@73g2000cwn.googlegroups.com... > > Hi everyone, > > I wrote some code and it seems ok to me but since it is going into a > high-use production environment, I wanted some peer-review if possible. > Basically, I wanted a way to know if an object is being "reset" and > only allow one thread to reset it at any one time. This is what I came > up with: > > Private _lockResetSync As Object = New Object() > Private _lockResetWaitEvent As ManualResetEvent = New > ManualResetEvent(False) > Private _IsResetting As Boolean = False > Public Sub Reset(ByVal cmd As Object) > Dim _ThisThreadIsResetting As Boolean = False > While Not _ThisThreadIsResetting ' pseudo-spin-lock for > thread safety > If _IsResetting Then > _lockResetWaitEvent.WaitOne() > Exit Sub > End If > SyncLock _lockResetSync > If Not _IsResetting Then > _lockResetWaitEvent.Reset() > _IsResetting = True > _ThisThreadIsResetting = True > End If > End SyncLock > End While > Try > ' !! Do time-consuming thread-safe stuff here > Finally > _IsResetting = False > _lockResetWaitEvent.Set() > End Try > End Sub > Public ReadOnly Property IsResetting() As Boolean > Get > Return _IsResetting > End Get > End Property > > I feel if two threads came into Reset() at the same clock-tick (hehe), > this would still work correctly. Also, external objects would know > what is going on. Will this work and if not, what is a better way to > do this? > > Thank you, > Michael >
cut, copy, and paste
Reservation algorithm Sending Email via VB.Net displaying resource file as Help Multithreading with DirectoryServices DirectoryServices Cast Error? Stopping Windows Service with Thread How to collect the data from input created by document.write() in ASP.NET? What would be a good way to add image files to my solution How do i read and write ini file using vb.net? |
|||||||||||||||||||||||