Линус Торвальдс (torvalds@cs.helsinki.fi)
Вт, 6 августа 1996 г., 12:47:31 +0300 (EET DST)
Сообщения отсортированы по: [дате] [теме] [теме] [автору]
Следующее сообщение: Бернд П. Циллер: «Re: Упс в get_hash_table»
Предыдущее сообщение: Линус Торвальдс: «Re: I / O request ordering»
В понедельник, 5 августа 1996 года, Питер П. Эйзерлох написал:
Нам необходимо четко понимать концепцию потоков. Слишком много людей
кажется, перепутать поток с процессом. Следующее обсуждение
не отражает текущее состояние Linux, а скорее
попытка остаться на высоком уровне обсуждения.
НЕТ!
Нет причин полагать, что "потоки" и "процессы"
отдельные лица. Вот как это традиционно делается, но я
лично я думаю, что это большая ошибка, думать так. Единственный
причина думать, что это исторический багаж.
И потоки, и процессы - это всего лишь одно: «контекст
выполнение ». Попытка искусственно различать разные случаи просто
самоограничения.
«Контекст исполнения», называемый здесь COE, является просто конгломератом
всего состояния этого СЕ Это состояние включает в себя такие вещи, как процессор
состояние (регистры и т. д.), состояние MMU (отображения страниц), состояние разрешений
(uid, gid) и различные «состояния связи» (открытые файлы, сигнал
обработчики и т. д.). Традиционно разница между «нитью» и
«Процесс» состоял главным образом в том, что потоки имеют состояние процессора (+ возможно
некоторое другое минимальное состояние), в то время как весь другой контекст происходит от
процесс. Тем не менее, это просто
один способ разделения общего состояния СЕ, и нет ничего, что говорит о том, что это правильный способ сделать это. Ограничивать себя
к такому образу просто глупо.
Linux думает об этом (и я хочу, чтобы все работало)
что не является такой вещью, как «процесс» или «нить». Есть
только совокупность COE (называемая Linux «задачей»). Разные СЕ
могут обмениваться частями своего контекста друг с другом и одним подмножеством из
что совместное использование является традиционной настройкой "потока" / "процесса", но это
действительно следует рассматривать только как подмножество (это важное подмножество, но
эта важность проистекает не из дизайна, а из стандартов: мы, безусловно,
хочу запускать соответствующие потоки программы поверх Linux
тоже).
Короче говоря: НЕ проектируйте с точки зрения потока / процесса мышления.
Ядро должно быть спроектировано на основе образа мышления Совета Европы, а затем
pthreads library может экспортировать ограниченный интерфейс pthreads для пользователей
кто хочет использовать этот взгляд на ИОВ.
Просто как пример того, что становится возможным, когда вы думаете, что СЕ
в отличие от потока / процесса:
- Вы можете создать внешнюю программу "cd", что традиционно невозможно в UNIX и / или process / thread (глупый пример, но идея
является то, что вы можете иметь такие "модули", которые не ограничены
традиционная настройка UNIX / threads). Сделайте:
Клон (CLONE_VM | CLONE_FS);
child: execve ("external-cd");
/ * «execve ()» будет разъединять ВМ, поэтому единственная причина, по которой мы
использованный CLONE_VM должен был ускорить процесс клонирования * /
- Вы можете сделать «vfork ()» естественным образом (это требует минимальной поддержки ядра, но эта поддержка идеально подходит для мышления CUA):
клон (CLONE_VM); * * тысяча пятьдесят семь
child: продолжать бежать, в конце концов execve ()
мама: жди execve
- Вы можете делать внешние "IO deamons":
клон (CLONE_FILES);
child: открыть дескрипторы файлов и т. Д.
мама: используйте фд, который ребенок открыл и вв.
Все вышеперечисленное работает, потому что вы не привязаны к потоку / процессу
способ мышления. Подумайте о веб-сервере, например, где CGI
Сценарии выполняются как «потоки исполнения». Вы не можете сделать это с
традиционные темы, потому что традиционные темы всегда должны делиться
все адресное пространство, так что вам придется ссылаться на все, что вы когда-либо
хотел сделать на самом веб-сервере («поток» не может запустить другой
исполняемый файл).
Думая об этом как о проблеме "контекста исполнения", ваш
задачи теперь можно выбрать для выполнения внешних программ (= отделить
адресное пространство от родителя) и т.д., если они хотят, или они могут для
пример поделитесь всем с родителем за исключением для файла
дескрипторы (так что под-"потоки" могут открывать много файлов без
родитель должен беспокоиться о них: они закрываются автоматически, когда
под-поток завершается, и он не использует fd в родительском).
Подумайте, например, о inetd с резьбой. Вы хотите низкие накладные расходы
fork + exec, поэтому с Linux вы можете вместо использования fork ()
вы пишете многопоточный inetd, где каждый поток создается с
просто CLONE_VM (разделяйте адресное пространство, но не делитесь дескрипторами файлов
так далее). Тогда ребенок может выполнить, если это был внешний сервис (rlogind,
например) или может это был один из внутренних сервисов inetd
(эхо, timeofday), в этом случае он просто делает свое дело и выходит.
Вы не можете сделать это с помощью "thread" / "process".
Linus