On 10/25/06, Levi Pearson <[EMAIL PROTECTED]> wrote:
I am one? I am one what? Are you disagreeing that memory protection is orthogonal to concurrency?
Oh, don't play dumb. You know what I mean. (I'm just messing with you). I'm not disagreeing that there are two distinct issues with concurrency. My earlier post made the suggestion of using threads in tandem with a high-level language that provides proper memory protection and heap data scope isolation. Given this situation I find that the built-in protection of OS processes is unneeded. There are trade-offs with both approaches - child-processes and threads. However, as stated before, I find all of the benefits of processes in threads plus the *option* to expose shared heap data and interact efficiently when that makes sense. The one thing that separate processes gives you that threads do not is a fresh user-land virtual address space of 2-3GB (depending on kernel config) on a 32-bit system -- on a 64-bit system the need for extra processes for additional memory space is unnecessary.
Of course you can choose not to take advantages of dangerous features. That's not the point. You're saying that threads are the best solution to all problems. I'm saying there are alternative concurrency models that provide additional safety from inadvertent errors. I don't see what your problem with this idea is.
It's not a matter of not choosing to take advantage of dangerous features, it's a matter of higher-level languages providing similar protection that the OS would provide via processes. I think there is tremendous value in the protection processes give you. I'm not disagreeing with your assertion that protection, even over-protection is good. It is good. It's just provided by a different mechanism than the OS in my case, and I find the model I work with to be more convenient and flexible.
Right. Like I said, some high level languages (read, Java) help out a lot.
I'm sure C# and others do this too. I've never written concurrent software with C# or Perl. Do they have similar features for threading? If so, I would choose threads over processes in those high-level languages as well.
One can always choose the best tool for the job, too. Assembly Language can express any computation that Java can, yet sometimes we choose to write programs in Java. Probably because of the increased safety, abstractions, and other good things.
You are exactly right. Increased safety and abstraction is the primary reason for using a higher-level language. You're no doubt drawing a similarity between these added protections and the protections of using child processes. I think that protection is good, but only needed if you're using a language/runtime that doesn't provide an even better model for concurrency.
The point of abstraction is to hide irrelevant details. If it ends up hiding important details instead, it creates more headaches and bugs than it prevents. See the following: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html I believe the Java memory model has been fixed now; I'm sure you'd know better than I do.
It has been fixed in Java 5, and even prior to Java 5 this was only an issue when trying to use a certain optimization during lazy instantiation of a shared object. In any case, my point is that if you are concerned about the details of mutil-thread interaction you can always use a thread in exactly the same manner you would use a child-process (don't share any heap data and don't do any locking) and you're no better of worse off. So you can't say processes are good and threads are bad because there are extreme examples of how to break yourself when using threads in an exotic way.
I'll assume you've momentarily forgotten about the non-composability of locks. You can't take two arbitrary, correct pieces of lock-based software, compose them, and assume the result is correct. This describes the problem better than I could: http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=332&page=3
Woopie-doo. Again, they are talking about the possible complexities of locks in highly threaded applications. I'm not saying that working with locks can't become complex, but your alternative of using child-processes doesn't solve the problem either. If your highly-concurrent application requires frequent interaction between threads/processes, then that's what it needs. Using processes will not solve this locking/interaction problem -- in fact it just avoids it all together or has to supplement it with IPC (and now your back to managing the race/dead-lock problems with the shared state data in your main process). As you mentioned before, on Linux, threads and processes are almost identical. About the only difference is that threads MAY access shared heap data while processes never can. So with threads you can choose to use locks and shared data sparingly with much success and far higher interaction performance than processes. That's my main point. Threads aren't evil and dangerous compared to processes when using high-level languages.
This isn't a matter of fear, it's a matter of managing complexity.
No, it's a matter of fear. You are a scaredy-scaredy cat. Meeeeooooowwww. (Again, I'm just joking around, please don't ever take my posts too seriously).
It is very easy to keep your program safe and correct by over- protecting your resources. That will, however, slow the program down. As you make your locks increasingly fine-grained, it becomes increasingly difficult to reason about the correctness of your program. This is just the way it is, whether you are cowardly or brave. Turning down tools that help manage this complexity is neither brave nor cowardly; it is stupid.
I agree. This is why I use Java instead of C and child-processes. The protection is worth it, and it this case, is more performant too.
I've read from people far smarter and more experienced than I am, and quite possibly smarter than you, hard as that may be for you to believe.
Hard to believe? You mean impossible to comprehend!!! Not only am I brilliant, but I'm incredibly humble too!
> That's true by virtue of the fact that a thread can be used just like > a child process but the reverse is not true. Threads give you the > option to touch shared data -- not an obligation to do so. Child > processes restrict your options. > Encapsulation via private class members restricts your options, too. So does restricting memory allocation and deallocation to the runtime system. You seem to be okay with those restrictions, which were largely added for reasons of safety and maintainability of software. Safer concurrency models provide a similar tradeoff.
No, now you're just avoiding my point. With encapsulation I have fine grained control over the data I will or will not expose. Likewise with threads I have control over what data I will or will not expose. With processes, I am not able to expose any shared data period. This is an absolute restriction. That's only a feature if your program doesn't require any interaction with the parent or other processes. In my experience this isn't a typical situation. You almost always need SOME level of interaction between a controlling thread (parent process) and it's worker (child process).
This is clearly better than the state of things in C, but it's far from the best we can do. But you can continue to use what you've got in Java if you really believe it's the best that can be.
I don't believe that Java's threading model is the best that could be, but I do find it more than worthy to utilize in the face of existing alternatives today. Given Java's model (an others who have similar capabilities), I don't find any virtues in the child-process model of concurrent programming compared to threads. But I do appreciate this discussion, I find your opinions to be very sound and well thought out. You are a true thinker and I appreciate your insights and opinions. I hope I haven't been too offensive with my pseudo insults above. -Bryan /* PLUG: http://plug.org, #utah on irc.freenode.net Unsubscribe: http://plug.org/mailman/options/plug Don't fear the penguin. */
