В традиционных ОС понятие нити тождественно понятию процесса. В действительности желательно иметь несколько нитей управления, разделяющих единое адресное пространство, но выполняющихся квазипараллельно.
Предположим, например, что файл-сервер блокируется, ожидания выполнения операции с диском. Если сервер имеет несколько нитей управления, вторая нить может выполняться, пока первая нить находится в состоянии ожидания. Это повышает пропускную способность и производительность. Эта цель не достигается путем создания двух независимых серверных процессов, потому что они должны разделять общий буфер кэша, который требуется им, чтобы быть в одном адресном пространстве.
На рисунке 3.9,а показана машина с тремя процессами. Каждый процесс имеет собственный программный счетчик, собственный стек, собственный набор регистров и собственное адресное пространство. Каждый процесс не должен ничего делать с остальными, за исключением того, что они могут взаимодействовать посредством системных примитивов связи, таких как семафоры, мониторы, сообщения. На рисунке 3.9,б показана другая машина с одним процессом. Этот процесс состоит из нескольких нитей управления, обычно называемых просто нитями или иногда облегченными процессами. Во многих отношениях нити подобны мини-процессам. Каждая нить выполняется строго последовательно и имеет свой собственный программный счетчик и стек. Нити разделяют процессор так, как это делают процессы (разделение времени). Только на многопроцессорной системе они действительно выполняются параллельно. Нити могут, например, порождать нити-потомки, могут переходить в состояние ожидания до завершения системного вызова, как обычные процессы, пока одна нить заблокирована, другая нить того же процесса может выполняться.
Рис. 3.9. а) Три процесса с одной нитью каждый
б) Один процесс с тремя нитями
Нити делают возможным сохранение идеи последовательных процессов, которые выполняют блокирующие системные вызовы (например, RPC для обращения к диску), и в то же время позволяют достичь параллелизма вычислений. Блокирующие системные вызовы делают проще программирование, а параллелизм повышает производительность.