Отличие процесса от потока linux
С помощью процессов можно организовать параллельное выполнение программ. Для этого процессы клонируются вызовами fork () или exec (), а затем между ними организуется взаимодействие средствами IPC. Это довольно дорогостоящий в отношении ресурсов процесс.
С другой стороны, для организации параллельного выполнения и взаимодействия процессов можно использовать механизм многопоточности. Основной единицей здесь является поток.
Поток представляет собой облегченную версию процесса. Чтобы понять, в чем состоит его особенность, необходимо вспомнить основные характеристики процесса.
- Процесс располагает определенными ресурсами. Он размещен в некотором виртуальном адресном пространстве, содержащем образ этого процесса. Кроме того, процесс управляет другими ресурсами (файлы, устройства ввода / вывода и т.д.).
- Процесс подвержен диспетчеризации. Он определяет порядок выполнения одной или нескольких программ, при этом выполнение может перекрываться другими процессами. Каждый процесс имеет состояние выполнения и приоритет диспетчеризации.
Если рассматривать эти характеристики независимо друг от друга (как это принято в современной теории ОС), то:
владельцу ресурса, обычно называемому процессом или задачей, присущи:
- виртуальное адресное пространство;
- индивидуальный доступ к процессору, другим процессам, файлам, и ресурсам ввода — вывода.
- состояние выполнения (активное, готовность и т.д.);
- сохранение контекста потока в неактивном состоянии;
- стек выполнения и некоторая статическая память для локальных переменных;
- доступ к пространству памяти и ресурсам своего процесса.
Все потоки процесса разделяют общие ресурсы. Изменения, вызванные одним потоком, становятся немедленно доступны другим.
При корректной реализации потоки имеют определенные преимущества перед процессами. Им требуется:
- меньше времени для создания нового потока, поскольку создаваемый поток использует адресное пространство текущего процесса;
- меньше времени для завершения потока;
- меньше времени для переключения между двумя потоками в пределах процесса;
- меньше коммуникационных расходов, поскольку потоки разделяют все ресурсы, и в частности адресное пространство. Данные, продуцируемые одним из потоков, немедленно становятся доступными всем другим потокам.
Источник
В чем разница между потоком и процессом?
Процессы и потоки связаны друг с другом, но при этом имеют существенные различия.
Процесс — экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Поток использует то же самое пространства стека, что и процесс, а множество потоков совместно используют данные своих состояний. Как правило, каждый поток может работать (читать и писать) с одной и той же областью памяти, в отличие от процессов, которые не могут просто так получить доступ к памяти другого процесса. У каждого потока есть собственные регистры и собственный стек, но другие потоки могут их использовать.
Поток — определенный способ выполнения процесса. Когда один поток изменяет ресурс процесса, это изменение сразу же становится видно другим потокам этого процесса.
Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.
Перейти к регистрации
Источник
процессы и потоки
помогите пожалуйста разобраться с понятиями процесса и потока в самом общем виде. я понимаю их так:
1. процессы существуют на уровне операционной системы. она при создании очередного потока выделяет ему ресурс, в первую очередь в виде кусочка оперативной памяти.
2. если в системе существуют несколько процессов, то они не могут взаимодействовать.
3. например если в одном процессе запущен браузер, а во втором процессе запущена игра, то игра никак не может узнать какие вкладки браузера открыты в данный момент.
4. при этом если процесс браузера породит дочерний поток(например в виде отдельного окна для диспетчера задач браузера), то они могут взаимодействовать потому что связаны отношением «родитель-наследник».
5. потоки создаются средствами языка программирования и существуют в пределах процесса.
6. при этом они могут взаимодействовать в пределах своего процесса.
7. например иметь доступ к переменной: менять её, удалять и т.д.
8. а также получать друг от друга сигналы типа mutex, semafor и т.д.
9. при этом потоки, которые живут в разных процессах не могут взаимодействовать.
10. если завершается процесс, то завершаются все его потоки тоже.
11. процессы выполняются по очереди. ОС выделяет каждому определённое время. в это время он выполняется, а остальные процессы не активны. далее по очереди каждый процесс становится активным, а остальные неактивными
12. ОС сама решает по какому принципу усыплять и оживлять процессы. в зависимости от типа ОС этот принцип бывает разный
если я что-то неправильно понимаю, то пожалуйста укажите на это и, если можно, посоветуйте что почитать чтобы вополнить пробел.
Если забанили в гугле , то восполняем пробел . Их много у него. 🙂 https://m.youtube.com/watch?v=Ni8udz5bRmU
Таненбаум в помощь — у него все это подробно описано
Всё не то чтобы так, у тебя очень много теоретических допущений, которые на практике диаметрально противоположны оказываются. Лучше посмотри как это на самом деле реализовано и работает, скажем, на примере си и линукса (это лишь 1 из вариантов, точнее даже несколько).
1.И тот и другой регистрируются в ОС, процесс более сложен — память, образ на диске, переменные окружения, командная строка и проч. 2. нет
4.просто могут, не потому что
5.создаются вызовом ОС, это объект для ОС, не языка
11.Потоки по очереди
Поток содержит код и данные. Процесс выполняет код выбранный из потока
Не путай человека, и сам не путайся
Тема обширная, чтобы тут расписывать, но пожалуй стоит сказать, что на уровне железа и процесс, и поток существуют. Для проца оба являются одним и тем же «задачей» (task), и разница только в том, какие области памяти и ресурсы ядра «видят» две/три/15 разных задач. Могут иметь общую память, а могут не иметь, смотря кому что отмапит ядро ос. На уровне ос разница уже существеннее, т.к. процесс это еще и учетная единица, где есть главный поток, есть ресурсы ядра вроде дескрипторов или примитивов синхронизации, есть состояние навроде cwd, есть ipc — shm, mmap, etc. Это ос создает различие на базе одного общего механизма многозадачности, которому самому абсолютно похрен на это все. Можешь рассматривать процесс как некую структуру в ядре, у которой есть не менее одного потока (на самом деле не менее нуля, если считать zombie за процессы). И потоки внутри процесса шарят как эту «структуру», так и память и прочее.
В теории можно написать такую ос, где можно было бы создать межпроцессный поток, который видел бы память и ядерные ресурсы двух процессов, а они (их главные потоки) друг друга не видели бы, но отдельным процессом он бы не был. И жил бы он пока оба процесса не кончились. Но так не делают. Но например низкоуровневый отладчик вроде gdb такое легко провернул бы, если бы захотел, прямо на линуксе.
3. например если в одном процессе запущен браузер, а во втором процессе запущена игра, то игра никак не может узнать какие вкладки браузера открыты в данный момент.
Сфига-ли? Хэндлы окон совершенно не против, чтобы их перехватывали и творили там что угодно, хоть член нарисуй в натуральную величину.
Ну, если лезть в дебри программирования. То есть два класса: Process и Thread. Чем они отличаются? Свойствами, вестимо. Я не знаю как ты, а я с первого раза в гугле нашел, чем отличается поток от процесса. Процесс — не лезет в другие участки памяти, кроме выделенного своего. Иначе- BSoD. Поток — лезет в участки памяти, но только своих приложений, которых может быть несколько. Ну, это грубо говоря.
Всё равно что инкапсуляцию и полиморфизм обьяснять на пальцах. Один хрен, не поймут.
В случае с Linux потоки — это тоже процессы, просто у потоков одного процесса есть общие сегменты памяти.
Процесс создаётся через системный вызов clone() (можно через fork(), но glibc’шный враппер fork() использует clone()), поток создаётся через clone(). Почитай ман этого системного вызова, там описано, какие части контекста процесса можно шарить.
Источник
Различие между процессами и потоками в Linux
после прочтения на ответ и «разработка ядра Linux» Робертом Лав и, впоследствии, на clone() системный вызов, я обнаружил, что процессы и потоки в Linux (почти) неразличимы для ядра. Между ними есть несколько настроек (обсуждается как «больше обмена» или «меньше обмена» в процитированном вопросе SO), но у меня все еще есть некоторые вопросы, на которые еще нужно ответить.
недавно я работал над программой, включающей пару POSIX и решил поэкспериментировать с этой предпосылкой. В процессе, который создает два потока, все потоки, конечно, получают уникальное значение, возвращаемое pthread_self() , , а не getpid() .
образец программы, которую я создал, следующий:
(это было скомпилировано [ gcc -pthread -o thread_test thread_test.c ] на 64-разрядной Fedora; из-за 64-разрядных типов, используемых для pthread_t полученные от , код потребует незначительных изменений для компиляции в 32-разрядных версиях.)
выход Я получаю следующее:
С помощью планировщика блокировки в gdb , я могу сохранить программу и ее потоки, чтобы я мог захватить то, что top говорит, что, просто показываю процессов, является:
и, показывая темы, говорит:
кажется совершенно ясным, что программы или, возможно, ядро имеют отличный способ определения потоков в отличие от процессов. Каждый поток имеет свой собственный PID в соответствии с top — почему?
3 ответов
все эти путаницы проистекают из того факта, что разработчики ядра изначально придерживались иррационального и неправильного представления о том, что потоки могут быть реализованы почти полностью в пользовательском пространстве, используя процессы ядра в качестве примитива, пока ядро предлагает способ заставить их делиться памятью и файловыми дескрипторами. Это привело к печально известной плохой реализации LinuxThreads потоков POSIX, которая была довольно неправильным названием, потому что она не давала ничего, отдаленно напоминающего семантику потока POSIX. В конце концов LinuxThreads был заменен (NPTL), но многие запутанные термины и недоразумения сохраняются.
первое и самое главное, чтобы понять, что «PID» означает разные вещи в пространстве ядра и пространстве пользователя. То, что ядро называет PID, на самом деле является идентификаторами потока уровня ядра (часто называемыми TIDs), не путать с pthread_t который является отдельным идентификатором. Каждый поток в системе, будь то в том же процессе или другом, имеет уникальный TID (или «PID» в терминологии ядра).
то, что считается PID в POSIX смысле «процесса», с другой стороны, называется «ID группы потоков» или «TGID» в ядре. Каждый процесс состоит из одного или нескольких потоков (процессов ядра) каждый со своим собственным TID (kernel PID), но все они имеют один и тот же TGID, который равен TID (kernel PID) исходного потока, в котором main работает.
, когда top показывает вам потоки, он показывает TIDs (PIDs ядра), а не PIDs (tgids ядра), и именно поэтому каждый поток имеет отдельный.
С появлением NPTL большинство системных вызовов, которые принимают аргумент PID или действуют на вызов
представьте себе какую-то»мета-сущность». Если сущность не использует ни один из ресурсов (адресное пространство, файловые дескрипторы и т. д.) своего родителя, то это процесс, а если сущность использует все ресурсы своего родителя, то это поток. Вы даже можете иметь что-то на полпути между процессом и потоком (например, некоторые общие ресурсы и некоторые не общие). Взгляните на системный вызов «clone ()» (например,http://linux.die.net/man/2/clone ) и вы увидите, как это делает Linux все внутренне.
теперь спрячьте это за какой-то абстракцией, которая делает все похожим на процесс или поток. Если абстракция безупречна, вы никогда не узнаете разницу между «сущностями» и «процессами и потоками». Абстракция не совсем безупречна, хотя-PID, который вы видите, на самом деле является»идентификатором сущности».
в Linux каждый поток получает поток код. Идентификатор потока основного потока выполняет двойную функцию в качестве идентификатора процесса (и довольно хорошо известен в пользовательском интерфейсе). Идентификатор потока является деталью реализации Linux и не связан с идентификатором POSIX. Для получения более подробной информации обратитесь к gettid системный вызов (недоступен из pure Python, так как он специфичен для системы).
Источник
Потоки против процессов в Linux
Недавно я слышал, как некоторые люди говорят, что в Linux почти всегда лучше использовать процессы вместо потоков, так как Linux очень эффективен в обработке процессов и потому, что с потоками связано очень много проблем (таких как блокировка). Тем не менее, я подозрительно, потому что кажется, что потоки могут дать довольно большой прирост производительности в некоторых ситуациях.
Поэтому мой вопрос заключается в том, что когда я сталкиваюсь с ситуацией, когда потоки и процессы могут справляться достаточно хорошо, мне следует использовать процессы или потоки? Например, если я писал веб-сервер, я должен использовать процессы или потоки (или их комбинацию)?
В Linux используется модель потоков 1-1, в которой (для ядра) нет различий между процессами и потоками — все это просто выполняемая задача. *
В Linux системный вызов clone клонирует задачу с настраиваемым уровнем общего доступа, среди которых:
- CLONE_FILES : использовать одну и ту же таблицу дескрипторов файлов (вместо создания копии)
- CLONE_PARENT : не устанавливать отношения родитель-потомок между новой задачей и старой (в противном случае child’s getppid() = parent’s getpid() )
- CLONE_VM : использовать то же пространство памяти (вместо создания копии COW )
fork() вызывает clone( наименьшее совместное использование ) и pthread_create() вызовы clone( наиболее общего доступа ) . **
fork Стоимость pthread_create копирования немного выше, чем копирование таблиц и создание сопоставлений COW для памяти, но разработчики ядра Linux постарались (и преуспели) в минимизации этих затрат.
Переключение между задачами, если они совместно используют одно и то же пространство памяти и различные таблицы, будет стоить чуть-чуть дешевле, чем если бы они не были общими, потому что данные могут быть уже загружены в кэш. Однако переключение задач по-прежнему происходит очень быстро, даже если ничего не передается — это то, что разработчики ядра Linux стараются обеспечить (и добиваются успеха в этом).
На самом деле, если вы работаете в многопроцессорной системе, отказ от совместного использования может быть полезен для производительности: если каждая задача выполняется на другом процессоре, синхронизация общей памяти обходится дорого.
* Упрощенный CLONE_THREAD вызывает CLONE_SIGHAND передачу сигналов для совместного использования (что необходимо , что разделяет таблицу обработчиков сигналов).
** Упрощено. Существуют SYS_fork и SYS_clone системные вызовы, и системные вызовы, но в ядре обе sys_fork и sys_clone являются очень тонкими оболочками для одной и той же do_fork функции, которая сама по себе является тонкой оболочкой copy_process . Да, термины process , thread и task используются довольно взаимозаменяемо в ядре Linux .
Источник