Как работает кооперативная многозадачность? - PullRequest
7 голосов
/ 29 июня 2011

Я прочитал эту Википедию текст срез:

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

Из любопытства, как человек бросает это время? Это какой-то вызов ОС? Давайте подумаем о случаях без вытеснения, таких как волокна или четные операции ввода-вывода, которые выполняют совместную многозадачность. Как они сдаются в это время?

Возьми это NodeJS пример:

var fs = require('fs');
fs.readFile('/path/to/file', function(err, data) {});

Для меня очевидно, что процесс ничего не делает, пока ожидает данные, но как V8 в этом случае отдает время другим процессам?

Давайте предположим, что нашей ОС является Linux / Windows.

Редактировать: я узнал, как Google делает это с их V8.

На Windows они в основном спят нулевое время:

void Thread::YieldCPU() {
  Sleep(0);
}

И в Linux они делают вызов ОС:

void Thread::YieldCPU() {
  sched_yield();
}

из sched.h.

Ответы [ 3 ]

4 голосов
/ 29 июня 2011

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

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

2 голосов
/ 29 июня 2011

Примером такой ОС является NetWare .В этой системе необходимо было вызывать определенную функцию (я думаю, что она называется ThreadSwitch или, возможно, ThreadSwitchWithDelay).И всегда было предположение, как часто это было необходимо.В каждом цикле, интенсивно использующем процессор в продукте, необходимо периодически вызывать одну из этих функций.

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

0 голосов
/ 29 июня 2011

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

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

Альтернатива(из этой вики) - многозадачность с упреждением, когда процесс вытесняет действие через определенное время, независимо от того, что он делает.Это означает, что что бы вы ни делали, оно не может работать вечно, потому что системный процесс его вытеснит.Однако он может быть менее эффективным, поскольку точки останова не определены.

...