Solaris Live Transcripts Index September 20, 2001
Chat Title: Multithreaded Programming with Pthreads This is a moderated chat LizA: Hello, and welcome to Solaris Live! Our guest today is Bil Lewis, co-author of "Multithreaded Programming With Pthreads". Bil is a former employee of Sun and currently a consultant. He has taught multithreading to more than 3000 programmers. Bil, I heard that on comp.programming.threads, the newsgroup, you and Dave Butenhof (DEC/Compaq) were having a debate about cancellation. Would you care to tell us about that? Bil: Dave and I have some differences of opinion on some things, although we basically concur on the big things. Here I contend that cancellation is *SO* difficult to use that you basically shouldn't ever use it. Dave maintains that it's just another arrow in your quiver and should be shot at the appropriate animals. But there aren't any such animals! say I. Show me one! Nonsense, says he. There *could* be one. Well don't use it unless you're 1000% certain you have such a beast, say I. And thus goes the discussion. So we haven't seen the beast, but he's more willing to admit its existence than I. That's all. We do agree that cancellation is very tricky to use. The whole point is that you now have to deal with asynchronous behavior in programs that are otherwise synchronous. (It's like trying to juggle balls when the juggler needs to take a bathroom break suddenly.) LizA: There has been some confusing discussion about "Double Checked Locking" on the net. Does it work? And if so, when *should* one use it? Bil: This is a very intricate, detailed issue. In the quest for ever faster CPUs and MP systems, they have weakened the requirements for the memory sytem on modern machines. This is good because they can run faster. It's bad because you don't know anything about what main memory will look like at any point in time. UNLESS you use a mutex. So, the old definition of DCL made assumptions about how memory would be ordered. And modern machines break this model. (If the CPU 1 writes word 1, then word 2, will CPU 2 see those writes in that order?) If you look at Doug Schmidt's new book on patterns for concurrency, he discusses this issue at the end of his DCL section. Now I've always contended that DCL is too awkward and too hard for us mortals to use and it doesn't save any time anyway. Doug insists I'm wrong and that it does have its uses. He's said so, but he's never shown me proof, so I'm... doubtful. In any case, BE CAREFUL! LizA: Does this memory model have related effects or implications for Java? Bil: Most certainly. First, DCL doesn't work in Java any more than it works in POSIX. (See the article on the web, "DCL is broken" which elaborates on this and shows the problem in detail.) Basically, you need to include memory barriers to make DCL work and you can't do that except with assembly code. For Java, there's the additional problem that Java REQUIRES its memory system to be consistent, and can NEVER allow an illegal memory reference (SEGV, SIGBUS). Thus there is a new memory proposal for Java which clarifies how Java MUST use memory barriers in places where it is not otherwise obvious. (See article by Doug Lea and Bill Pugh on Java memory model.)
LizA: Can C++ member functions be used as the startup routine for
Bil: The best answer is NO! Don't do that! Although you might get away with it, C++ and C linking conventions are NOT required to be identical. So on many systems with many C++ compilers, you CAN use a static member function (it MUST be static, of course) as an argument and it will all work just fine, or it *might* not. And should you decide to port to another
#include <pthread.h>
#include <iostream>
extern "C" void* startIt( void* );
class Fred {
pthread_t tid;
friend void* startIt( void* );
void* runMe() throw() {
std::cout << "Done" << std::endl; return NULL;
}
public: int start() throw() {
return pthread_create( &tid, NULL, startIt, this );
}
pthread_t id() const throw() {
return
tid;
}
};
void* startIt( void* p ) {
Fred* pF = static_cast<Fred*>(p);
return pF->runMe();
}
int main() {
Fred f;
int s;
if( (s = f.start()) ) return s;
std::cout << "Started" << std::endl;
void* status;
pthread_join( f.id(), &status );
pthread_exit( 0 ); }
So, use a C function! LizA: What are Windows NT fibers and when should I use them, if ever? Bil: Fibers are an abomination against nature and the gods of programming! They are the begat of the forces of darkness, created to confuse and cause consternation in the world!! Oh, I mean, fibers were created for reasons that are probably not really proper and they should not be used with regularity. Jeffrey Richter, Advanced Windows, 3rd Ed., p.971 states that "The fiber functions were added to the Win32 API to help companies quickly port their existing UNIX® server applications to Windows NT." (blah) The following sentences say that fibers are targeted to the proprietary user level thread-like quirks some companies did for whatever reason (ease of programming, performance). Although I have problems with the Win32 threads interface, in and of itself, it's not terrible and it does work reasonably well. The fibers part of it IS bad, and just shouldn't be used. Ever. IMHO. LizA: Bil, let me ask you a different kind of question...How DID you get started with threads? Bil: Well... it all started back in the early pleistociene... I was in university in '70 and there were these two giant electronic brains which nobody knew how to use... PDP 8's. (The best RISC machine *ever*! 1MHz cycle time, 4k RAM, tape readers...) So we built an interface so they could talk to each other. Then I had to write a language which would run in parallel using both CPUs, and thus I became enchanted with the magic of parallel computing, threading, Async behavior, and all that fine stuff. LizA: From those humble beginnings, obviously the interest has grown quite a bit. How much ARE people using threads these days? Bil: Quite a bit, actually. The whole point is that we now have these big MP machines you can buy for practically nothing. (A 64 CPU Starfire costs... ~$1m?) Folks want to use all that power. So we need to write threaded programs to do that. (Threads are by far the best way of taking advantage of multiple CPUs.) It's true with POSIX. Folks write a program once and can run it on Suns, DECs, HPs, IBMs, HALs, etc. It's even more true with Java. As a matter of fact, the Java version of threading has become SO easy to use, that many people just jump in without knowing as much as they should and just start hacking. (Which leads to problems sometimes. Writing threaded programs is easy. Writing CORRECT threaded programs is harder.) LizA: Bil, let me ask you one more question. How should I use priority levels? Bil: You shouldn't. In all but the most exceptional cases, for non-realtime programs, you should simply ignore them. In POSIX, in Java, in Win32. If you're doing realtime work, that's different. But here I'm talking only timeshared programs. You should write your programs so that the threads do their work, so that you have a "reasonable" number of threads for the size of the machine you have (and there's lots to be said there! See the FAQ.) But you generally simply write the program, make it as good and as efficient as you can and then trust the scheduler to do its job. ALMOST always, the default scheduler on all of the OSs is just fine and you won't have problems. So, ignore them. I have seen many programs that try to get clever with priorities and only make things harder for themselves. I have NEVER seen a non-realtime program that benefited from changing priority levels. As Dave will tell you, there COULD be some. But I haven't seen 'em. LizA: That's all we have time for today. Do you have any parting comments, Bil? Bil: First, I recommend reading a good book on threads. Mine, Dave's, Devang/Kleinman/Smallders, Ken Norton's. Don't just read code or man pages. You need a good book. Then there's the newsgroup, comp.programming.threads. On my web page, I maintain the FAQ, have lots of code examples, a list of books, and other information: www.LambdaCS.com. And of course there's ME! I teach classes, do consulting, etc. Feel free to contact me: Bil@www.LambdaCS.com. And above all, Program Properly, Proficiently, Pleasurably, and Profitably! -Bil LizA: Thanks for being our guest today, Bil. Your book, "Multithreaded Programming With Pthreads", is reviewed on the Solaris Developer Connection at http://soldc.sun.com. Be sure to join us on October 18, noon PDT, when our guests are Rajat P. Garg and Ilya Sharapov, authors of "Techniques for Optimizing Applications: High Performance Computing". September 20, 2001 | ||||||||
|
| ||||||||||||