Потоки по сравнению с (разветвленными) процессами

Я предполагаю, что Вы понимаете, что обе этих команды называют другую версию времени, правильно?

встроенная версия удара

% time

Время GNU иначе./usr/bin/time

% \time

Встроенное time команда к bash может быть считан на здесь:

% help time
time: time [-p] PIPELINE
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    The return status is the return status of PIPELINE.  The `-p' option
    prints the timing summary in a slightly different format.  This uses
    the value of the TIMEFORMAT variable as the output format.

GNU time, /usr/bin/time, обычно более полезно, чем встроенное.

Относительно Вашей проблемы точности это покрыто здесь в этой сути GitHub, конкретно:

Почему время удар, более точный затем время GNU?

Встроенное время команды удара дает точность миллисекунды выполнения, и время GNU (обычно/usr/bin/time) дает точность сотой доли секунды. Времена (2) syscall дает времена в часах и 100 часах = 1 секунда (обычно), таким образом, точность похожа на время GNU. Что время удар с помощью то, так, чтобы это было более точно?

Время Bash внутренне использует getrusage (), и время GNU использует времена (). getrusage () намного более точен из-за разрешения микросекунды.

Вы видите сотые доли секунды со следующим примером (см. 5-ю строку вывода):

% /usr/bin/time -v sleep .22222
    Command being timed: "sleep .22222"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.22
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 1968
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 153
    Voluntary context switches: 2
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Больше разрешения может иметься с помощью удара time управляйте как так, и можно управлять разрешением:

# 3 places 
% TIMEFORMAT='%3R'; time ( sleep .22222 )
0.224

Из руководства Bash по переменным:

TIMEFORMAT
The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the time reserved word should be displayed. The ‘%’ character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows; the braces denote optional portions.

%%
A literal ‘%’.

%[p][l]R
The elapsed time in seconds.

%[p][l]U
The number of CPU seconds spent in user mode.

%[p][l]S
The number of CPU seconds spent in system mode.

%P
The CPU percentage, computed as (%U + %S) / %R.

The optional p is a digit specifying the precision, the number of fractional digits after a decimal point. A value of 0 causes no decimal point or fraction to be output. At most three places after the decimal point may be specified; values of p greater than 3 are changed to 3. If p is not specified, the value 3 is used.

The optional l specifies a longer format, including minutes, of the form MMmSS.FFs. The value of p determines whether or not the fraction is included.

If this variable is not set, Bash acts as if it had the value

$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed.

9
05.05.2014, 03:59
5 ответов
[117270]Большинство неUnix многопроцессорных операционных систем (ОС) используют вызов "spawn()" или что-то подобное для генерации нового процесса ОС или потока управления. Вызов spawn() имеет тенденцию быть очень сложным, с большим количеством опций и накладных расходов. Одним из нововведений Unix было предоставление гораздо более низкого накладного способа создания процессов - fork(). Unix позаботился о множестве необходимых опций для spawn(), позволяя произвольное количество обработки перед второй половиной spawn(), с помощью функции exec().

Поскольку Unix и его варианты использовались все больше и больше, создание накладных процессов с низким уровнем накладных расходов было признано полезным и использовалось. На самом деле, она использовалась настолько широко, что люди хотели еще более низкие накладные расходы на создание процессов, и поэтому родилась идея "потоков". Изначально, потоки полностью обрабатывались исходным процессом (и такие программы, как JVM, могут делать это с "зелеными потоками"); но обработка многопоточного планирования является сложной и часто выполнялась неправильно. Поэтому существует более простой, промежуточный способ работы с потоками, когда операционная система управляет планированием, но некоторые накладные расходы сохраняются за счет (обычно) совместного использования адресного пространства между потоками.

На ваш вопрос трудно ответить, потому что существует несколько различных, но связанных между собой понятий, которые все являются "потоками", и для подробного описания того, на какое прилагательное вы ссылаетесь, вам понадобится прилагательное. С другой стороны, понимание различий, вероятно, приведет вас к конкретному ответу, который вы хотите получить. Посмотрите на такие вещи, как "легковесные процессы", "пользовательские потоки" и "rfork()" для более подробной информации[117275].

8
27.01.2020, 20:04
[117238]Потоки и вилки на самом деле являются двумя различными концепциями, обе из которых существуют в Unix/Linux системах (и обе могут быть использованы в Си/Си++).

aptitude reinstall <package name(s)>
Идея fork() - это (в сущности) создание отдельного процесса, который имеет тот же самый код выполнения, что и родительский процесс, и который начинает выполняться со строки вилки. Цель использования вил с функциями исполнения заключается в том, чтобы выполнять функции, закрывающие процесс, который их вызвал, когда они заканчиваются. Таким образом, обычно вилка получает PID каждого процесса (дочерний всегда равен 0) и заставляет родителя ждать, пока дочерний процесс завершит выполнение функции.

Потоки используются для параллелизма (напомним, что родитель ждет дочернего процесса, как правило, в вилочной программе). Поток, такой как pthread на Си/Си++ (выполните поиск в Google), будет выполняться параллельно основному процессу и может делиться глобальными переменными и глобальными функциями с исходной программой. Поскольку Java-потоки ведут себя подобным образом, я бы предположил, что они ведут себя скорее как эти потоки, чем как процесс форкинга.

В принципе, есть разница между форкингом и многопоточностью. Они делают совершенно разные вещи (хотя и кажутся похожими). Эти понятия может быть трудно понять, но вы можете изучить их через (обширное) исследование, если у вас есть честное желание их понять.

EDIT #1

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

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip

3
27.01.2020, 20:04
[117230] Идея потоков и процессов примерно одинакова: вы вскрываете путь выполнения. Иначе потоки и процессы различаются в таких вещах, как память. Т.е. процессы имеют разное пространство ВМ, в то время как потоки делят между собой все, что существовало до разделения.

В основе работы потоков и процессов лежит использование вызова clone() (man 2 clone):

В отличие от fork(2), clone() позволяет дочернему процессу делиться частями контекст его выполнения с вызывающим процессом, например, памятью пространство, таблица файловых дескрипторов и таблица сигнала обработчики. (Обратите внимание, что на этой странице руководства, "процесс вызова". обычно соответствует "родительскому процессу". Но см. описание CLONE_PARENT ниже.)

Основное использование функции clone() заключается в реализации потоков: многопоточность контроля в программе, которая одновременно выполняется в общей памяти. space.

dpkg -S /usr/share/man/man1

Различия происходят от флагов, которые передаются для клонирования(). Как видно из страницы man, fork и threading - это всего лишь набор предопределенных параметров для clone(). Однако с ним можно делать и пользовательские вещи.[117237]

13
27.01.2020, 20:04
[117358] И JVM, и Apache MPM полагаются на ядро для нативных потоков. То есть они используют операционную систему для их планирования. Естественно, оба нуждаются в собственном API для отслеживания вещей.

Stackoverflow уже имеет несколько вопросов, связанных с этим:

JVM native threads[117834], подробнее смотрите [117835]этот ответ[117836].

Apache имеет два типа МП-модулей: Prefork, с одним процессом на поток, и Worker, который обрабатывает несколько потоков: [117837]МПМ Apache[117838]. Обратите внимание на ссылку на [117839]codebucket

1
27.01.2020, 20:04

Если вилка + exec используется для порождения процесса, то что такое высокоуровневая версия для нити? Как JVM или рабочий МП-модуль порождает потоки?

Это специфично для платформы, но на linux и я бы предположил, что многие другие POSIX-совместимые системы используют локальную реализацию

pthreads

osascript -e 'tell application "System Events"' \
          -e 'keystroke "s" using {command down, option down}' \
          -e 'end tell'
, пользовательского многопоточного API. Например:

запускает новый поток, вызывая [117703]somefunc[117704] в качестве первой точки выполнения.

Можно также создавать потоки -- отличные от вилок тем, что они разделяют одно и то же глобальное пространство памяти [117705]heap[117706] родительского процесса, вместо того, чтобы получать его дубликат (но потоки нот каждый выполняется с независимой [117707]стековой памятью [117708]) -- с системным вызовом [117709]клона()[117710], на котором построен pthreads поверх.[117413].

1
27.01.2020, 20:04

Теги

Похожие вопросы