Процессы, потоки и квартиры
Процесс — это коллекция виртуального пространства памяти, кода, данных и системных ресурсов. Поток — это код, который должен быть последовательно выполнен в процессе. Процессор выполняет потоки, а не процессы, поэтому каждое приложение имеет по крайней мере один процесс, а процесс всегда имеет по крайней мере один поток выполнения, известный как основной поток. В дополнение к основному потоку процесс может содержать несколько потоков.
Процессы взаимодействуют друг с другом через сообщения, используя технологию удаленного вызова процедур (RPC) корпорации Майкрософт для передачи информации друг другу. Вызывающий объект не имеет никакой разницы между вызовом, исходящим из процесса на удаленном компьютере, и вызовом, исходящим из другого процесса на том же компьютере.
Когда поток начинает выполняться, он продолжается до тех пор, пока он не будет завершен или пока не будет прерван потоком с более высоким приоритетом (действием пользователя или планировщиком потоков ядра). Каждый поток может выполнять отдельные разделы кода или несколько потоков могут выполнять один и тот же раздел кода. Потоки, выполняющие один и тот же блок кода, поддерживают отдельные стеки. Каждый поток в процессе совместно использует глобальные переменные и ресурсы этого процесса.
Планировщик потоков определяет, когда и как часто следует выполнять поток, в соответствии с сочетанием атрибута класса priority процесса и базового приоритета потока. Атрибут класса priority процесса задается путем вызова функции SetPriorityClass и базового приоритета потока с помощью вызова Метода SetThreadPriority.
Многопоточные приложения должны избегать двух проблем с потоком: взаимоблокировок и рас. Взаимоблокировка возникает, когда каждый поток ожидает выполнения других действий. Элемент управления вызовами COM помогает предотвратить взаимоблокировки в вызовах между объектами. Состояние гонки возникает, когда один поток завершается перед другим, от которого он зависит, в результате чего первый использует неинициализированное значение, так как последний еще не предоставил допустимое значение. COM предоставляет некоторые функции, специально разработанные для предотвращения состояния гонки на серверах вне процесса. (См. раздел Вспомогательные средства реализации внепроцессного сервера.)
Архитектура подразделения и com-потоков
Хотя COM поддерживает модель с одним потоком на процесс, распространенную до появления нескольких потоков выполнения, вы можете написать код, чтобы воспользоваться преимуществами нескольких потоков, что приводит к более эффективным приложениям, позволяя выполнять один поток, а другой поток ожидает завершения некоторой длительной операции.
Использование нескольких потоков не гарантирует лучшую производительность. На самом деле, так как факторинг потоков является сложной проблемой, использование нескольких потоков часто приводит к проблемам с производительностью. Ключ заключается в том, чтобы использовать несколько потоков только в том случае, если вы уверены в том, что делаете.
Как правило, самый простой способ просмотреть архитектуру потоков COM — подумать, что все COM-объекты в процессе разделены на группы, называемые квартирами. Объект COM находится ровно в одной квартире, в том смысле, что его методы могут быть юридически напрямую вызваны только потоком, принадлежащим этой квартире. Любой другой поток, который хочет вызвать объект, должен проходить через прокси-сервер.
- Однопотоковые квартиры состоят только из одного потока, поэтому все COM-объекты, которые находятся в однопотоковом объекте, могут принимать вызовы методов только из одного потока, который принадлежит к этой квартире. Все вызовы методов к COM-объекту в однопотоковом объекте синхронизируются с очередью сообщений Windows для потока однопотокового подразделения. Процесс с одним потоком выполнения — это просто особый случай этой модели.
- Многопоточные квартиры состоят из одного или нескольких потоков, поэтому все COM-объекты, которые находятся в многопоточном помещении, могут принимать вызовы методов непосредственно из любого из потоков, принадлежащих многопоточному объекту. Потоки в многопоточных подразделениях используют модель, называемую свободными потоками. Вызовы COM-объектов в многопоточной квартире синхронизируются самими объектами.
Описание обмена данными между однопоточными и многопоточными квартирами в рамках одного процесса см. в разделе Однопотоковое и многопоточное взаимодействие.
Процесс может иметь ноль или несколько однопоточных квартир и ноль или одно многопоточное подразделение.
В процессе первой инициализируется main квартира. В однопотоковом процессе это единственная квартира. Параметры вызова маршалируются между квартирами, а COM обрабатывает синхронизацию с помощью обмена сообщениями. Если вы назначите несколько потоков в процессе как свободные, все свободные потоки находятся в одном экземпляре, параметры передаются непосредственно в любой поток в этом объекте, и необходимо обрабатывать всю синхронизацию. В процессе как со свободными потоками, так и с многопоточными потоками, все свободные потоки находятся в одной квартире, а все остальные квартиры являются однопоточными. Процесс, который выполняет com-работу , представляет собой коллекцию квартир с не более чем одной многопоточной квартирой, но любым количеством однопоточных квартир.
Модели потоков в COM предоставляют механизм для совместной работы клиентов и серверов, использующих различные архитектуры потоков. Вызовы между объектами с разными моделями потоков в разных процессах естественным образом поддерживаются. С точки зрения вызывающего объекта все вызовы объектов за пределами процесса ведут себя одинаково, независимо от того, как вызывается объект, является потоком. Аналогичным образом с точки зрения вызываемого объекта поступающие вызовы ведут себя одинаково, независимо от модели потоков вызывающего объекта.
Взаимодействие между клиентом и внепроцессным объектом является простым, даже если они используют разные потоковые модели, так как клиент и объект находятся в разных процессах. COM, взаимодействующий между клиентом и сервером, может предоставить код для взаимодействия потоковых моделей, используя стандартную маршалинг и RPC. Например, если однопоточный объект вызывается одновременно несколькими клиентами со свободными потоками, вызовы будут синхронизированы com путем размещения соответствующих оконных сообщений в очереди сообщений сервера. Объект будет получать по одному вызову каждый раз при извлечении и отправке сообщений. Однако необходимо соблюдать определенную осторожность, чтобы обеспечить правильное взаимодействие внутрипроцессных серверов с клиентами. (См. раздел Проблемы с потоком внутрипроцессного сервера.)
Самая важная проблема при программировании с многопоточной моделью — сделать код потокобезопасными, чтобы сообщения, предназначенные для определенного потока, отправились только в этот поток и доступ к потокам был защищен.
Дополнительные сведения см. в следующих разделах:
- Выбор потоковой модели
- Однопотоковые квартиры
- Многопоточные квартиры
- Однопотоковый и многопоточный обмен данными
- Проблемы с потоком внутрипроцессного сервера
- Доступ к интерфейсам между квартирами
Учебники. Программирование для начинающих.
Programm.ws — это сайт, на котором вы можете почитать литературу по языкам программирования , а так-же посмотреть примеры работающих программ на С++, ассемблере, паскале и много другого..
Программирование — в обычном понимании, это процесс создания компьютерных программ.
В узком смысле (так называемое кодирование) под программированием понимается написание инструкций — программ — на конкретном языке программирования (часто по уже имеющемуся алгоритму — плану, методу решения поставленной задачи). Соответственно, люди, которые этим занимаются, называются программистами (на профессиональном жаргоне — кодерами), а те, кто разрабатывает алгоритмы — алгоритмистами, специалистами предметной области, математиками.
В более широком смысле под программированием понимают весь спектр деятельности, связанный с созданием и поддержанием в рабочем состоянии программ — программного обеспечения ЭВМ. Более точен современный термин — «программная инженерия» (также иначе «инженерия ПО»). Сюда входят анализ и постановка задачи, проектирование программы, построение алгоритмов, разработка структур данных, написание текстов программ, отладка и тестирование программы (испытания программы), документирование, настройка (конфигурирование), доработка и сопровождение.
Подробный курс Java
Многопоточность
Процессы, потоки и приоритеты
Прежде чем приступить к разговору о многопоточности, следует уточнить некоторые термины.
Обычно в любой многопоточной операционной системе выделяют такие объекты, как процессы и потоки. Между ними существует большая разница, которую следует четко себе представлять.
Процесс
Процесс (process) — это объект, который создается операционной системой, когда пользователь запускает приложение. Процессу выделяется отдельное адресное пространство, причем это пространство физически недоступно для других процессов. Процесс может работать с файлами или с каналами связи локальной или глобальной сети. Когда вы запускаете текстовый процессор или программу калькулятора, вы создаете новый процесс.
Поток
Для каждого процесса операционная система создает один главный поток (thread ), который является потоком выполняющихся по очереди команд центрального процессора. При необходимости главный поток может создавать другие потоки, пользуясь для этого программным интерфейсом операционной системы.
Все потоки, созданные процессом, выполняются в адресном пространстве этого процесса и имеют доступ к ресурсам процесса. Однако поток одного процесса не имеет никакого доступа к ресурсам потока другого процесса, так как они работают в разных адресных пространствах. При необходимости организации взаимодействия между процессами или потоками, принадлежащими разным процессам, следует пользоваться системными средствами, специально предназначенными для этого.
Приоритеты потоков в приложениях Java
Если процесс создал несколько потоков, то все они выполняются параллельно, причем время центрального процессора (или нескольких центральных процессоров в мультипроцессорных системах) распределяется между этими потоками.
Распределением времени центрального процессора занимается специальный модуль операционной системы — планировщик. Планировщик по очереди передает управление отдельным потокам, так что даже в однопроцессорной системе создается полная иллюзия параллельной работы запущенных потоков.
Распределение времени выполняется по прерываниям системного таймера. Поэтому каждому потоку дается определенный интервал времени, в течении которого он находится в активном состоянии.
Заметим, что распределение времени выполняется для потоков, а не для процессов. Потоки, созданные разными процессами, конкурируют между собой за получение процессорного времени.
Каким именно образом?
Приложения Java могут указывать три значения для приоритетов потоков. Это NORM_PRIORITY, MAX_PRIORITY и MIN_PRIORITY.
По умолчанию вновь созданный поток имеет нормальный приоритет NORM_PRIORITY. Если остальные потоки в системе имеют тот же самый приоритет, то все потоки пользуются процессорным времени на равных правах.
При необходимости вы можете повысить или понизить приоритет отдельных потоков, определив для них значение приоритета, соответственно, MAX_PRIORITY или MIN_PRIORITY. Потоки с повышенным приоритетом выполняются в первую очередь, а с пониженным — только при отсутствии готовых к выполнению потоков, имеющих нормальный или повышенный приоритет.
В чем разница между потоком и процессом?
Процессы и потоки связаны друг с другом, но при этом имеют существенные различия.
Процесс — экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Поток использует то же самое пространства стека, что и процесс, а множество потоков совместно используют данные своих состояний. Как правило, каждый поток может работать (читать и писать) с одной и той же областью памяти, в отличие от процессов, которые не могут просто так получить доступ к памяти другого процесса. У каждого потока есть собственные регистры и собственный стек, но другие потоки могут их использовать.
Поток — определенный способ выполнения процесса. Когда один поток изменяет ресурс процесса, это изменение сразу же становится видно другим потокам этого процесса.
Разбор взят из книги Гейл Л. Макдауэлл «Cracking the Coding Interview» (есть в переводе).
Процессы и потоки
П роцесс – это исполняемая копия приложения. Например, когда вы открываете приложение MS Word, то запускаете процесс, исполняющий программу MS Word. Поток – отдельное исполняемое задание внутри процесса. Процесс может содержать множество исполняемых потоков. После запуска приложения исполняется главный поток, который далее может порождать другие потоки.
Каждый процесс обладает собственной памятью. Потоки же, которые запущены внутри процесса, разделяют память между собой. Процесс внутри операционной системы обладает собственным идентификатором. Потоки существуют внутри процесса и обладают идентификатором внутри работающего приложения. Каждый из потоков имеет свой собственный стек (он не делит его с другими потоками и другие потоки не могут в него залезть) и собственный набор регистров (поток не изменит значения регистра другого потока во время работы). Часто потоки называют «легковесными» процессами, так как они требуют гораздо меньше ресурсов для работы, чем новый процесс. В зависимости от реализации, обычный настольный компьютер может эффективно использовать от единиц, до десятков тысяч потоков.
- Идентификатор процесса
- Окружение
- Рабочая папка
- Регистры
- Стек
- Куча
- Файловый дескриптор
- Общие библиотеки (dll, so)
- Инструменты межпроцессорного взаимодействия (пайпы, очереди сообщений, семафоры или обобщённая память)
- Специфические для операционной системы ресурсы
- Stack Pointer (указатель на вершину стека, на самом деле «своего» стека, как у процесса, у потока нет)
- Регистры
- Свойства (необходимые для планировщика, такие как приоритет или политики)
- Специфичные для потока данные
- Специфические для операционной системы ресурсы
Многозадачность и параллелизм
М ногозадачные системы позволяют запускать несколько задач одновременно. Многозадачность не обязательно обозначает истинную параллельность выполнения задач: такие системы существуют достаточно давно и появились тогда, когда процессоры были одноядерными. Все задачи получают от планировщика временной промежуток, в течение которого выполнять работу. После чего задача переходит в состояние ожидания. Все задачи имеют свой приоритет, соответственно, чем выше приоритет, тем больше времени задача может работать.
Многозадачные системы на однопоточном процессоре создают иллюзию синхронного выполнения нескольких процессов. Пусть у нас есть три процесса. Если каждый из них работает время t1, t2 и t3, то общее время выполнения будет равно t1+ t2 + t3.
Последовательное выполнение трёх процессов на однопоточном процессоре
Если теперь мы разобьём каждую из задач на N частей, то общее время выполнения будет dt1*N+dt2*N+dt3*N+dts*N*N, где dts – это время, затрачиваемое на восстановление контекста выполнения задачи (на работу планировщика).
Работа каждого процесса на однопоточном процессоре разбита на временные промежутки
С одной стороны, последовательное выполнение трёх задач без накладных расходов на переключение между задачами должно быть гораздо быстрее. Однако на практике часто бывает иначе. Если процесс выполняет много операция ввода-вывода или работает с внешними ресурсами, то большую часть времени он простаивает, ожидая данные. Это время простоя занимает другая задача. Таким образом, общее время выполнения становится меньше.
Когда процесс большую часть своего времени простаиват в ожидании ресурсов, то параллельное выполнение нескольких задач может происходить быстрее, чем последовательное
Если у нас имеется одна «числодробительная» задача, то никакого преимущества не будет. Но стоит помнить, что в ряде случаев даже на одноядерном процессоре такая искусственная параллелизация может существенно ускорить выполнение.
Для многоядерных систем всё яснее: если задача разбита на несколько потоков, то каждый из них может выполняться реально параллельно. То есть, если решать задачу в 4 потока вместо одного, то потенциально она станет работать в 4 раза быстрее. Очевидно, что где-то есть подвох…
Во-первых, ускорение работы с увеличением числа процессоров и ядер растёт нелинейно и имеет для данной задачи какой-то потолок (см. закон Амдала). А во-вторых, задача сильно усложняется при наличии общих ресурсов.
Совместный доступ к ресурсам
К огда несколько потоков делают каждый своё дело, не разделяя память, то они могут сильно ускорить работу. Дополнительные издержки потребуются только для выделения ресурсов под эти потоки и для передачи им необходимых данных. Когда несколько потоков должны общаться друг с другом, передавать данные, обрабатывать один объект, то есть совместно обращаться к одному ресурсу (обычно это общий участок памяти), то возникают так называемые race conditions – состояния гонки – когда результат работы зависит от порядка доступа к ресурсам.
Например, нам нужно сложить два массива a и b одинаковой длины и поместить результат в массив c. Каждое значение c[i] зависит от a[i] и b[i] и не зависит от остальных. Мы можем разделить массивы на несколько участков, и каждый из потоков будет заниматься сложением только этих участков, не пересекаясь с остальными потоками. У них всех будут общие переменные a, b и c, но они будут всегда независимо обращаться только к отдельным областям памяти.
Второй типичный пример: банковский счёт. Пусть два человека имеют доступ до одного счёта. На счету 10000. Пользователь A снимает со счёта 8000. Второй пользователь запрашивает остаток. Операция первого пользователя не успела завершиться и на счету указано 10000. Второй пользователь снимает 5000. В тот момент, когда он отправил заявку на снятие денег со счёта, деньги уже снялись, и на счету осталось 2000. В данном случае возможно несколько исходов. Самый лучший, когда у второго пользователя выпадет ошибка, и он ничего не получит. Ситуация, когда второй пользователь снимет деньги и счёт станет -3000. А также ситуация, когда оба снимут деньги и на счету останется 2000 или 5000.
POSIX threads
И сторически сложилось, что каждый производитель железа реализовывал свою проприетарную версию потоков. Эти реализации сильно отличались друг от друга, создавая большие проблемы для программистов и не давая возможности писать переносимое программное обеспечение.
В связи с этим, появилась необходимость в стандарте для потоков. Для UNIX-подобных операционных систем был принят стандарт IEEE POSIX 1003.1c (1995). Реализация библиотеки для работы с потоками в соответствии с этим стандартом и называется POSIX threads, или pthreads.
В настоящее время большинство производителей совместно со своими собственными интерфейсами для работы с потоками предлагают Pthreads. Pthreads обычно представляет собой набор типов и функций на языке си, описанных в файле pthread.h и реализованных в .h, .lib, .dll и т.д. файлах, поставляемых с библиотекой. Иногда pthread входит в состав другой библиотеки (например, libc).
ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 sypachev_s_s@mail.ru Stepan Sypachev students
Всё ещё не понятно? – пиши вопросы на ящик