Operating systems may adopt one of many different scheduling strategies, which generally fall into the following categories:
The term time-sharing is no longer commonly used, having been replaced by simply multitasking.
The first efforts to create multiprogramming systems took place in the 1960s. Several different programs in batch were loaded in the computer memory, and the first one began to run. When the first program reached an instruction waiting for a peripheral, the context of this program was stored away, and the second program in memory was given a chance to run. The process continued until all programs finished running.
Multiprogramming doesn't give any guarantee that a program will run in a timely manner. Indeed, the very first program may very well run for hours without needing access to a peripheral. As there were no users waiting at an interactive terminal, this was no problem: users handed a deck of punched cards to an operator, and came back a few hours later for printed results. Multiprogramming greatly reduced the waiting.
The early OS/360 primary control program (PCP) followed the above model but was replaced the very next year, 1967, by MFT which limited the amount of CPU time any single process could consume before being switched out.
Early multitasking systems consisted of suites of related applications that voluntarily ceded time to each other. This approach, which was eventually supported by many computer operating systems, is today known as cooperative multitasking. Although it is rarely used in larger systems, Microsoft Windows prior to Windows 95 and Windows NT, and Mac OS prior to Mac OS X both used cooperative multitasking to enable the running of multiple applications simultaneously. Windows 9x also used cooperative multitasking, but only for 16-bit legacy applications, much the same way as pre-Leopard PowerPC versions of Mac OS X used it for Classic applications. Cooperative multitasking is still used today on RISC OS systems.
Because a cooperatively multitasked system relies on each process to regularly give time to other processes on the system, one poorly designed program can cause the whole system to hang.
Preemptive multitasking allows the computer system to more reliably guarantee each process a regular "slice" of operating time. It also allows the system to rapidly deal with important external events like incoming data, which might require the immediate attention of one or another process.
At any specific time, processes can be grouped into two categories: those that are waiting for input or output (called "I/O bound"), and those that are fully utilizing the CPU ("CPU bound"). In early systems, processes would often "poll", or "busywait" while waiting for requested input (such as disk, keyboard or network input). During this time, the process was not performing useful work, but still maintained complete control of the CPU. With the advent of interrupts and preemptive multitasking, these I/O bound processes could be "blocked", or put on hold, pending the arrival of the necessary data, allowing other processes to utilize the CPU. As the arrival of the requested data would generate an interrupt, blocked processes could be guaranteed a timely return to execution.
The earliest pre-emptive multitasking OS available to home users was the AmigaOS released in 1985. Pre-emptive multitasking was later adopted on Apple Macintoshes by MacOS 9.x as an additional API, i.e. the application could be programmed to use the pre-emptive or co-operative model, and all legacy applications were multitasked cooperatively within a single process. Mac OS X, being a Unix-like system, uses pre-emptive multitasking for all native applications, although Classic applications may be multitasked cooperatively as they run in fact under Mac OS 9 running as OS X process.
Much similar model is used in Windows 9x and Windows NT family, where native 32-bit applications are multitasked preemptively, and legacy 16-bit Windows 3.x ones - cooperatively within a single process, although in the NT family it is possible to force 16-bit application to run as a separate preemptively multitasked process. 64-bit editions of Windows, both for the x86-64 and IA-64 architectures no longer provide support for legacy 16-bit applications, and thus provide pre-emptive multitasking for all supported applications.
Pre-emptive multitasking is also a standard feature on all versions of Unix and Unix-like operating systems, including Linux, Solaris and BSD with its derivatives.
Threads were born from the idea that the most efficient way for cooperating processes to exchange data would be to share their entire memory space. Thus, threads are basically processes that run in the same memory context. Threads are described as lightweight because switching between threads does not involve changing the memory context.
While threads are scheduled preemptively, some operating systems provide a variant to threads, named fibers, that are scheduled cooperatively. On operating systems that do not provide fibers, an application may implement its own fibers using repeated calls to worker functions. Fibers are even more lightweight than threads, and somewhat easier to program with, although they tend to lose some or all of the benefits of threads on machines with multiple processors.
Some systems directly support multithreading in hardware.
The operating system therefore restricts the memory accessible to the running program. A program trying to access memory outside its allowed range is immediately stopped before it can change memory belonging to another process.
Another key innovation was the idea of privilege levels. Low privilege tasks are not allowed some kinds of memory access and are not allowed to perform certain instructions. When a task tries to perform a privileged operation a trap occurs and a supervisory program running at a higher level is allowed to decide how to respond. This created the possibility of virtualizing the entire system, including virtual peripheral devices. Such a simulation is called a virtual machine operating system. Early virtual machine systems did not have virtual memory, but both are common today.
Bigger computer systems were sometimes built with a central processor(s) and some number of I/O processors, a kind of asymmetric multi-processing.
Over the years, multitasking systems have been refined. Modern operating systems generally include detailed mechanisms for prioritizing processes, while symmetric multiprocessing has introduced new complexities and capabilities.