On Mon, Nov 24, 2008 at 5:08 AM, WT <[EMAIL PROTECTED]> wrote: >>- First, don't use NSOperationQueue unless you can stand to have your >>app crash from time to time, or unless you can require Snow Leopard. >>It's crashy and I have no particular hope that Apple is going to make >>it stop being crashy at any time in the 10.5 series. > > Is that the general consensus? I've now seen a few examples and they all > seem to work fine. Then, again, extrapolating from a small sample is always > dangerous...
No, it's not a general consensus. It's something I discovered on my own, and posted about it here. I haven't received any overall confirmation that it's broken, but my simple test project was able to reliably crash on perhaps half a dozen different hardware configurations. (And fail to crash on quite a few more.) If you like, you can go through the original thread here and come to your own conclusions: http://www.cocoabuilder.com/archive/message/cocoa/2008/10/30/221452 If you want to know more about it, please feel free to ask me. Depending on exactly what you're after, you might look into other facilities provided by Cocoa. If you start a worker thread that runs an NSRunLoop, you can then use a method like -performSelector:onThread:withObject:waitUntilDone: to execute a method on that thread. You miss out on a lot of what NSOperation provides, but depending on exactly what you need that may not be a big problem. For what you're describing, you could perhaps run the simulation from an NSTimer on the secondary thread, then communicate the value changes to it using this method. >>- When multithreading for the purposes of optimization as you're >>doing, treat it as any other optimization. That is, measure and >>profile your app before you do anything else to it. Trying to figure >>out where to put the threads when you don't even know what parts of >>your app are slow is pointless. Just as it's a bunch of wasted effort >>to carefully hand-craft a super fast assembly language version of a >>function that only runs one time for one millisecond, it's likewise a >>bunch of wasted effort to carefully come up with a multithreaded >>implementation of such a function. In your case, if the simulation >>engine only takes up, say, 10% of your CPU time compared to display, >>then the absolute possible best speed gain you could ever see from >>shoving it into a background thread would be 10%, probably not worth >>all the work and risk. > > Generally, I'd agree with you on what you just said, but I have to disagree > this time because I am not using multithreading for the purpose of > optimization. I'm using it because it's a requirement that the user should > be able to change certain aspects of the simulation while the simulation is > running. For instance, in the example of the bouncing balls, if the user > were to rotate the container (the custom NSView), the balls should continue > moving, rather than stop until the user has finished rotating the view. This > requirement necessitates a complete separation between running the > simulation and dealing with user events, and that spells multithreading to > me. I see, I misunderstood the purpose of your question. Have you thought about replacing the main loop of your simulation with a timer on the main thread instead of multithreading it? If the individual timesteps in your simulation happen fast enough then this can be a very good solution. Basically, instead of having a loop that does something like "while(!done) simulationStep();", you just set up an NSTimer to call simulationStep() repeatedly. The downside is that if your individual steps are slow, the user interface will not be very responsive, so this is not always a good way to go. I mention it because it avoids multithreading and all the difficulties that brings along, so it can be nice, but of course it's not always the best. >>- When multithreading, use message passing and immutable objects as >>much as possible. The nightmare case for multithreading is when you >>have some gigantic object with a ton of shared state that gets used >>from four different threads at once and has a complex hierarchy of >>locks to ensure that none of them step on each other's toes. If you >>can decompose your operations into individual immutable messages which >>you fire across to other threads, you remove a lot of shared data >>which is where a lot of the problems with multithreading come from. >>NSOperation is actually a nice way to do this, too bad it's pretty >>much unusable. > > Yes, I'm aware of the problems you mentioned. My application, however, will > likely not suffer severely from those problems, since the data sharing in it > fits the producer/observer pattern, as opposed to a model where several > threads all read and write shared data. The UI produces values that must be > passed to the simulation engine and the simulation engine produces data to > be displayed. The simulation engine never writes back to the UI controls and > the drawing engine never writes back to the simulation engine. The flow of > data is always unidirectional. This model (producer/observer) is the ideal > case to apply messaging but there is still the issue of when the new data is > inserted into the current thread. Message-passing and immutable objects do > not necessarily solve the issue of data synchronization. What I need is a > way to guarantee that new data will not be inserted in the middle of the > simulation (or drawing). In Java, I'd fire the notification message in a > separate thread and would make sure that it blocks until an appropriate lock > is released. In Cocoa, I was hoping not to have to get down to that level of > detail and, instead, simply take advantage of the ability to set > dependencies between NSOperation objects added to an NSOperationQueue. (Yes, > I know that, deep down, NSOperation and NSOperationQueue may use threads and > locks and all that good stuff to do their magic. The point is, *I* don't > want to have to deal with that level of detail, if I can help it). Sounds like you're in good shape then. My experience has been that best practices in Cocoa are much like best practices in other multithreaded programming. The major difference is that Cocoa provides facilities for things like message passing that in many other circumstances you'd have to build up yourself from primitives. This is of course a great help if message passing is what you're after, but overall it's the same basic stuff. Mike _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]