But even if you have a multi-processor (SMP) system, there will always be more tasks than processors on your system, so switching is still required.
A thread is OS/2's unit for administrating task switches. A program can contain several threads, but per definition, it will have at least one. But since a program can have more than one thread, switching can take place even between threads in the same program. This is called multithreading. As opposed to many other operating systems, OS/2 fully supports this, and it even does so in a very fancy and reliable way.
The part of the OS/2 kernel which switches between threads is called the "scheduler".
The term "thread" was chosen because within one thread program instructions are executed sequentially, while between threads you may never be sure which instruction of one thread will be executed before or after an instruction of another thread. It is only OS/2 which keeps switching between threads without the thread even knowing about it (or, on SMP systems, threads might actually run concurrently on several processors).
Well-programmed OS/2 software uses several threads to ensure that the user gets a quick response to his input and mouse actions. For example, if you execute a command in a program which will take a long time, a program should start a secondary thread for this task. While this new thread is working in the background, the user interface (on the main thread of the program) is ready again for new input.
Not-so-well-programmed OS/2 software uses only one thread for both the user interface and executing tasks. As a result, while executing a task, the user interface is blocked.
Threads can have different priorities. In general, a thread with a higher priority gets more processor time that one with lower priority. To be more precise, OS/2 looks at thread priorities if more than one thread is internally marked as "ready". By contrast, threads which are currently "blocked" need no CPU time anyway, so for them, priorities do not matter until they are unblocked again. Note that on your typical OS/2 system, the large majority of threads will be in "blocked" state at any given point in time.
OS/2 is capable of controlling thread priorities in a very refined way. It differentiates between four priority classes:
A few examples:
Within the "regular priority" class however OS/2 ensures that no thread
"starves", i.e. never gets processor time, by dynamically raising each
thread's priorities after a certain time automatically. This period of time
is determined by the MAXWAIT CONFIG.SYS
setting. Moreover, OS/2
boosts a thread's priority temporarily if it is to receive keyboard input,
if the process of the thread runs in the foreground, or if the thread is
currently doing I/O.
These dynamic adjustments are only then performed if CONFIG.SYS does
not contain the command PRIORITY=ABSOLUTE,
which is not
recommended. (This is why you will not find that setting in the
"OS/2 Kernel" object.)
Each process contains common data as well as controls access to system resources. Processes are protected against each other in that OS/2 prohibits access to memory which does not belong to the process attempting to access it ("memory protection").
By contrast, several threads within a process may all access the process's memory, because memory is administered on a per-process basis. The same applies to other system resources such as open files.
To summarize, threads own only the CPU until they are interrupted by OS/2
(over which they have little control, other than setting their priorities).
By contrast, processes own everything else: files, devices, and memory.