[Nomen-dev] A radical idea: a non-threaded language
Brought to you by:
bhurt
|
From: Brian H. <bh...@sp...> - 2002-03-26 23:17:42
|
I was ranting at my brother yesterday about threads, and general why unix is better than windows sort of verbage. I'll skip the unix-vr.s-windows comments as irrelevent, and just focus on threads. My main points were: 1) Threads encourage hard to find, hard to reproduce bugs- deadlocks, resource starvation, race conditions, etc. Worse yet, the logic behind what is and isn't safe is subtle, see: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 2) Threads are, for most uses they are put to these days, inefficient or simply to make up for poor design. What are the three most common uses of threads? A) Handle inputs/outputs from multiple streams simultaneously- web servers, print spoolers, etc. This is better handled by asyncronous I/O routines (poll, select, aio, etc). Actually, this is best handled by fork() and copy on write pages, but that's kinda OS dependent. B) Split a CPU intensive computation across multiple CPUs. OK, This is a legitimate usage of threads- but I think that using fork() and COW pages would work about as well. Better yet, use a network protocol like MPI (IIRC) and allow you to split your computation across multiple computers (Beowulf cluster, anyone?). C) Maintain the illusion of responiveness in a slow GUI. This implies both bad library design and bad code architecture. The fact that the MFC is rife with these problems doesn't make it acceptable. So the idea occurred to me- do we have to have threads in the language at all? Wait a minute- before you start pelting me with those rotten vegitables, think about it. Most multithreaded code is bad code- do we want to be encouraging the production of bad code? The other alternative is to do something to make threads safer. There are two possible ideas here: 1) Have the virtual machine use green threads, but don't support kernel threads. This gives us a level of control, but fails the primary *legitimate* purpose of multithreading- using multiple CPUs. This could be offset using fork and various RPC protocols (CORBA, COM, etc). 2) Compiler-added locking. Using algorithms similiar to those used by GCs, it's possible to determine what objects are accessible from multiple threads. You would then have multiple different "memory regions"- each thread has a memory region of objects only it can access, and a shared region of objects multiple threads can reach. When the thread follows a reference into the common area, it has to obtain a lock. Determining the minimum number of locks necessary would be tricky. Avoiding deadlocks would be trickier yet. Hmm. Actually, choice #2 has some potiential. I shall have to think about it some more. Brian |