Thread versus Process

Why are threads and processes different? Here are some reasons, both subjective and objective. By their definition, threads do not have to be visible outside of a process. This allows (but does not require) thread creation and scheduling to be largely performed at user level. Some advantages of this are: Fewer kernel context swaps in most cases. 250 instructions for a null system call can swamp the cost of a fast context switch. Though a user level scheduler has to call the kernel sometimes, experience has shown this to be much less frequent. Less checking of arguments. The kernel should not let a buggy or malicious client mess up its invariants but it is the norm for a buggy client to have the ability to screw up its own libraries. Note that though it is the norm it can cause problems and that is one reason why some of us are pushing for safe languages, where the features of the language that can screw up other facilities are isolated (e.g. mfree, pointer arithmetic, unchecked array dereferencing, passing addresses of objects outside the scope where the object is known to exist). This has been done with Modula-3 and we are working on doing this with C++.
Fewer data structures shared between all processors. Since each process has its own ready queue the global ready queue is not accessed so much. (This advantage is not inherent but it is typical.)
Allows for scheduling policy to more easily be adjusted on a per process basis as much of the policy lives in a library. The old disadvantages of user level schedulers have been addressed a number of times, most completely by Anderson et al. in their work on scheduler activations. I think this was reported at the latest SOSP. The problems they address include:
Page faults blocking the kernel thread being used by the user level scheduler
Priorities not working between threads in different processes They have also designed an RPC system that for many workloads works entirely at user level.
Threads are a programming mechanism, like for loops or procedures. They make it easier to write programs that have certain attributes.
Processes are containers that are used to run a program on many OSs, in particular Unix. The user of a program should not have to care what particular implementation techniques were used in the implementation of the program. Processes act as firewalls between programs, allowing separate processes to fail independently from each other. The Plan 9 model solves the same problem that threads address with coroutines plus processes forked with the option to share nearly everything. Though the Plan 9 process model (a.k.a. Variable Weight Processes) allows for a myriad of different types of processes sharing who knows what with who knows whom, the actual patterns of sharing are usually either of the thread variety (nearly everything) or of the normal process variety (nearly nothing), anything else is too confusing. With a good implementation threads can have the power of a process (independent blocking, ability to exploit multiprocessors) and, in general, the weight of a coroutine. - If process = program then handling errors and debugging is much easier as the system knows the boundary of what should be grouped together and Threads inside processes allow this equation to hold much more uniformly. RPC and nonshared memory (traditional) process groups can sometimes cause this equation to break down, but with much less frequency than it would in the Plan 9 model.