Matthew Zaleski Posted March 23, 2009 Report Share Posted March 23, 2009 I'm still getting up to speed with LVOOP concepts, mainly translating my brain views of other OOP languages into what LVOOP requires. Having read the stickied thread and attachments, I'm still hazy about race conditions. Here is the example I conjured: Class FileLineReader: # reads a text file line by line Members:file refnum other fluff about the file [*]Methods: OpenFile() - Opens a file GetNextLine() - returns string SeekToLine() - seeks to a given line in text file more fluff I create an instance of this class. Can I have worker threads that each have a copy via wire of this object, where each worker is called GetNextLine()? How is LabVIEW enforcing that my file refnum isn't being hit by 2 reads at same time? I know there are other ways to design this to avoid contention but I'm curious about this edge case. Quote Link to comment
mzu Posted March 23, 2009 Report Share Posted March 23, 2009 QUOTE (Matthew Zaleski @ Mar 21 2009, 07:41 PM) Class FileLineReader: # reads a text file line by line I create an instance of this class.Can I have worker threads that each have a copy via wire of this object, where each worker is called GetNextLine()? How is LabVIEW enforcing that my file refnum isn't being hit by 2 reads at same time? I know there are other ways to design this to avoid contention but I'm curious about this edge case. Refnum is a reference, so when wire forks you get exactely the same refnum in both wires. AFAIK, file access serialisation occurs at Windows IO manager (VFS subsystem in Linux), in other words LabVIEW will allow you to call two file access functions with the same refnum (translated later to a file handle) at the same time. The question is what kind of a behaviour do you expect from such a class in such a case? IMHO, you will have so synchronize execution between two worker threads somehow to get predictive behaviour. I have a limited expertise with OOP design in LabVIEW, but on one of my projects I have used Singleton pattern for the case like yours (http://forums.ni.com/ni/board/message?board.id=170&message.id=216094&requireLogin=False' target="_blank">LabVIEW OOP design patterns This pattern (together with other things) explicitly serialises an object access. It worked Quote Link to comment
mje Posted March 23, 2009 Report Share Posted March 23, 2009 QUOTE (Matthew Zaleski @ Mar 21 2009, 07:41 PM) Can I have worker threads that each have a copy via wire of this object, where each worker is called GetNextLine()? How is LabVIEW enforcing that my file refnum isn't being hit by 2 reads at same time? The short answer is it doesn't. But there are subtleties. Assuming GetNextLine() is not re-entrant, only one task will ever be able to call the method at once since there will be only one copy of the VI in memory. So there's some built in synchronization right there, but it's not really OOP that's buying you that, the principle is the same for any VI with default entrancy. Something to consider: you have multiple methods that would seem to operate on the file reference, like SeekToLine(), and maybe other "fluff". So even though LabVIEW will keep you from calling GetNextLine() simultaneously in two places, you'll likely still need to build some kind of synchronization mechanism to ensure that say, GetNextLine and SeekToLine are not called at the same time from different tasks. There are many ways, mzu mentioned the singleton pattern. Properly build a semaphore into your class will also work. Also be aware of the context of split wires if you have non-reference data in your class, or if references change. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.