5 ms·
I'm curious, could he (or you) have written a program in any other languages (like Go) and not have worried about these issues? Honestly, I got some mild goose
by neya 13y ago
I'm curious, could he (or you) have written a program in any other languages (like Go) and not have worried about these issues?
Honestly, I got some mild goose-bumps after realizing the number of Zeroes that 12 million had.
- lmm 13y agoI'd use scala actors and not have to worry about this issue. Anything that avoids shared-memory communication means you're safe from this kind of interaction. IMO raw threads are too dangerous to use as anything other than a primitive to implement higher-level concurrency on.
- Anderkent 13y agoThere are many languages where you don't have to worry about this particular issue. Clojure for example enforces immutability (which means you cannot unsafely share the reference, since the reference is immutable too) and provides safe sharing mechanisms that would prevent this.
- noelwelsh 13y agoThey could have written it in Java and not worried about these issues. I was writing Java code using channels to communicate between threads in 2000 (i.e. the stuff that Go has.) Back then we had to download Doug Lea's concurrency package to get this stuff. For about a decade it has been in the standard library.
- jtheory 13y agoEven without Doug Lea's extensions (though they did help making it more efficient and/or easier to understand), it's been possible to do this safely in Java from v1.0 -- just synchronize and notify() or notifyAll() as needed. I think the chief problem is that the developer hadn't learned the basics of multithreaded programming yet, and didn't realize s/he needed to know them. That's an extremely harsh way to learn a little lesson, regardless.
- zemo 13y agoyou could, but it's not very clear why you would want this to be multithreaded to begin with, since it appears the author wants the program to quit as soon as the value fails validation. It looks like it's multithreaded just for the hell of it. Anyway, you could do it in Go like this: http://play.golang.org/p/3Wy_S42jVj http://play.golang.org/p/3Wy_S42jVj basically what you do is you create a goroutine that reads a pointer to the Point value, checks it, and if it's bad, exits. In your main loop, send a * Point down the channel. That basically means: I made this thing. It's yours now. Do what you want with it. Then in the reporting channel, the value is read and checked. The same pointer is sent back in a reply, meaning "I'm done with this, you can have it back now". You almost certainly shouldn't be doing this; I'm just doing this to emulate the fact that the original example is using the same reference from both threads. Yes, this is very, very weird and no, you should not do this in your own programs. Anyway, we take that pointer back, dereference it, and assign it to a new Point value, which is completely weird and I still don't understand. (presumably the original author mistakenly thought this was an atomic way to set both fields on the Point.) In this way, the two goroutines (the main and reporting goroutine) are able to use channels to synchronize access to some shared memory. This is a pretty silly use of concurrency, though, because in this case, it's probably more clear to just use a mutex to lock and unlock your Point. Again, yes, this is sloppy and weird, but it represents the same behavior as the original program, but properly synchronized.
- taway2012 13y agoIMHO, there is a subtle difference between your version and the version posted. You assuming a "real" producer-consumer relationship. But the posted code seems to imply a sort of "supervisor-worker" relationship. The "supervisor" "snoops" on the worker's state and raises an alarm if the worker is doing something weird. As you stated at the end, synchronizing around currentPos seems to be most reasonable solution (assuming that's possible). That guarantees that no Point method is running while currentPos's state is being examined.
- zemo 13y agoI'm under the impression that the supervisor wants to stop the worker as soon as its doing something wrong; not do something like check every so often, and stop only when the supervisor notices. Anyway, what you're describing is pretty easy too. Basically all you do is make a channel of Point, and have the supervisor read on that. The worker just does some work, and tries to send his value down the channel. If someone's listening, send the value. This is pretty straightforward, but probably not safe in the real world, because the worker just keeps on working; it doesn't wait for a confirmation that its work is ok. http://play.golang.org/p/J8Xgh8S18b http://play.golang.org/p/J8Xgh8S18b If you want to structure it such that the supervisor can stop the worker, ask the worker what it's doing, look at the data, and then reply with "ok, you can continue now", there's a handful of ways to do it. Now we're getting pretty real-world, and things get a little bit more intricate, but you can do it like this: http://play.golang.org/p/hXYNmCm8lg http://play.golang.org/p/hXYNmCm8lg the trick being that you send a channel over another channel. There's a handful of ways you could structure this; there may be a cleaner way.