What is the difference between time sharing and multiprogramming?

Both terms are used to describe a computer process known as multi-tasking, where a single CPU core switches between tasks periodically to reduce inefficiency and wasted time, and to allow the user to perform multiple tasks at the same time. The difference between the two are technical distinctions, rather than a difference in their intended effect.

Multiprogramming was the first form of multi-tasking, and introduced in the the concept of yielding. When an instruction could not be completed immediately (such as when reading from a disk or other slow peripheral, the current task was set aside, and another task would run until the data from the paused task was ready.

Some time later, time sharing was introduced to allow more fine-grained control over the yielding process. The first form was known as cooperative time sharing. In this model, a program would run for a while and then willingly relinquish control so that another process could have a chance. This was referred to as cooperative time sharing. This model had some drawbacks, as programs could be written incorrectly and fail to yield in a timely manner, causing the system to become slow and unresponsive. Additionally, programs cooperated in the same unprotected memory space, so a crash of one program meant that the entire system could be brought down by a single fault.

Advances in hardware allowed for the processes to be interrupted by the operating system. This brought about the next generation of time sharing, known as preemptive time sharing. Along with this model came advances in virtual memory that allowed each program to run in its own virtual memory space. No longer would a single program cause a systemic crash, and a program could no longer fail to yield (in theory, at least).