Я также хотел бы выразить глубокую благодарность за поддержку и понимание моей жене Кристине за то, что она каждый раз терпела мое многочасовое торчание в подвале с полнейшим ее игнорированием!

Типографские соглашения

В тексте данной книги для обеспечения различимости технической терминологии используется ряд типографских соглашений. В целом, примененные здесь стандарты оформлении текстового материала соответствуют таковым в публикациях документов POSIX. Ниже в таблице приведены образцы принятых типографских соглашений.

Тип текста Пример оформления Тексты программ if (stream == NULL) Опции команд -lR Команды make Переменные окружения PATH Файлы и имена путей /dev/null Имена функций exit() Комбинации клавиш Ctrl-Alt-Del Клавиатурный ввод Текст, который вы набираете Клавиши Enter Вывод программ login: Именованные константы NULL Типы данных unsigned short Литералы 0xFF, "message string" Имена переменных stdin

Этот значок указывает на что-либо важное или полезное в тексте книги.

Основные понятия о процессах и потоках

Прежде, чем мы начнем обсуждать потоки, процессы, кванты времени и другие замечательные «концепции диспетчеризации», давайте поговорим об аналогиях.

Сначала я хотел бы проиллюстрировать, как функционируют потоки и процессы. На мой взгляд, лучший способ (о глубинном изучении систем реального времени сейчас речь не идет) — это вообразить поведение наших потоков и процессов в некоторой привычной для нас обстановке.

Процесс как жилой дом

Давайте используем для построения аналогий о процессах и потоках объект, который мы используем повседневно — наш собственный дом.

Дом реально представляет собой контейнер с некоторыми атрибутами (общая площадь дома, число спален, и т.д.).

Если рассматривать жилой дом с этой точки зрения, он ничего не делает сам по себе. Дом — пассивный объект, в этом он аналогичен процессу. Поговорим об этом вкратце.

Потоки как обитатели дома

Люди, живущие в доме, суть активные объекты — они живут в комнатах, просматривают телепрограммы, готовят пищу, принимают душ, и т.д. Скоро мы поймем, что потоки функционируют аналогично.

Однопоточность

Если вы когда-либо жили в одиночестве, вы знаете, каково это — вы можете делать в доме все, что вы пожелаете и когда вы пожелаете, потому что в доме больше никого нет. Если вы пожелаете включить стерео, принять душ, приготовить обед, что угодно — вы просто идете и делаете это.

Многопоточность

Ситуация в корне изменится, если вы введете в дом еще одного человека. Скажем, вы женитесь. Теперь у вас есть супруга, живущая в этом же доме вместе с вами. Теперь уже вы не сможете попасть в душ в любой момент времени — придется каждый раз сначала проверять, нет ли там вашей супруги.

Если вы оба — взрослые и ответственные люди, о вопросах безопасности обычно можно не беспокоиться. Вы будете уверены в том, что другой совершеннолетний человек будет уважать ваши правила, принципы и жизненное пространство и не попробует тайком поджечь кухню, и т.д.

А если теперь добавить в дом несколько детей — тут все станет еще интереснее.

Назад к процессам и потокам

Так же как и дом занимает некоторый участок земли в жилом массиве, так и процесс занимает некоторый объем памяти компьютера. Аналогично тому, как и обитатели в доме могут свободно войти в любую комнату, в которую пожелают, потоки в процессах все вместе имеют общий доступ к этой памяти. Если поток получает доступ к некоему объекту (мама покупает игрушку), все другие потоки немедленно получают к нему доступ, потому что этот объект существует в общем адресном пространстве — в доме. Аналогично, если процесс распределяет для себя память, эта память становится доступной для всех потоков. Хитрость здесь состоит в том, что необходимо знать, должна ли эта память быть доступной для всех потоков в процессе. Если это так, то доступ потоков к ней придется синхронизировать. Если это не так, то будем считать, что эта память относится к одному конкретному потоку. В этом случае, поскольку только один поток имеет доступ к этой памяти, можно считать, что синхронизация не потребуется — не будет же этот поток сам ставить себе подножки!

Из нашего повседневного опыта мы знаем, что вещи не так просты, как кажутся. Теперь, когда мы рассмотрели основные характеристики (резюме: любой объект является разделяемым!) давайте обратимся к более интересным ситуациям и выясним, чем же они так интересны.

На рисунке, представленном ниже, показано, как мы в дальнейшем будем представлять потоки и процессы. Процесс здесь — это круг, отображающий «контейнерную» концепцию (адресное пространство), а три ломаных линии — это потоки. Вы найдете найдете подобные иллюстрации далее во всех разделах этой книги.

Процесс как контейнер потоков.

Взаимное исключение

Если вы хотите принять душ, и в доме есть еще кто-то, и этот кто-то уже в ванной, вам придется подождать. Как же поток функционирует в аналогичной ситуации?

Потоки используют то, что мы называем взаимным исключением (mutual exclusion). Означает это в значительной степени то, о чем вы и подумали — несколько потоков являются взаимно исключающими, когда речь идёт идет об определенном ресурсе.

Если вы хотите принять душ, это значит, что вы хотите получить эксклюзивный доступ к ванной комнате. Для этого вы должны сначала войти в ванную, а затем закрыть ее дверь изнутри. Если при этом данной ванной комнатой попытается воспользоваться кто-либо другой, его остановит запертая дверь. После того как вы закончили свои дела в ванной, вы откроете дверь и этим позволите еще кому-либо получить доступ в душ.