Подсказка: .
является ссылкой на старую совместную многозадачную библиотеку, которая поставлялась с ранними версиями CFront (вы также можете скачать на этой странице).
Если вы прочтете статью " Набор классов C ++ для совместного программирования стилей ", все станет намного понятнее.
Добавление немного:
Я не достаточно старый программист, чтобы использовать библиотеку задач. Однако я знаю, что C ++ был разработан после того, как Страуструп написал симуляцию в Simula, у которой было много тех же свойств, что и у библиотеки задач, поэтому мне всегда было интересно об этом.
Если бы я выполнил упражнение из книги, я, вероятно, сделал бы это следующим образом (обратите внимание, я не проверял этот код или даже не пытался его скомпилировать):
class Scheduler {
std::list<*ITask> tasks;
public:
void run()
{
while (1) // or at least until some message is sent to stop running
for (std::list<*ITask>::iterator itor = tasks.begin()
, std::list<*ITask>::iterator end = tasks.end()
; itor != end
; ++itor)
(*itor)->run(); // yes, two dereferences
}
void add_task(ITask* task)
{
tasks.push_back(task);
}
};
struct ITask {
virtual ~ITask() { }
virtual void run() = 0;
};
Я знаю, что люди не согласятся с некоторыми из моих выборов. Например, используя структуру для интерфейса; но структуры ведут себя так, что наследование от них является публичным по умолчанию (где наследование от классов является приватным по умолчанию), и я не вижу никакого значения в частном наследовании от интерфейса, так почему бы не сделать публичное наследование по умолчанию?
Идея состоит в том, что вызовы ITask :: run () будут блокировать планировщик до тех пор, пока задача не достигнет точки, в которой она может быть прервана, и в этот момент задача вернется из метода run, и дождаться, пока планировщик вызовет бегите снова, чтобы продолжить. «Кооператив» в «кооперативной многозадачности» означает «задачи говорят, когда их можно прервать» («сопрограмма» обычно означает «кооперативная многозадачность»). Простая задача может делать только одну вещь в своем методе run (), более сложная задача может реализовывать конечный автомат и может использовать его метод run (), чтобы выяснить, в каком состоянии находится объект в настоящее время, и выполнить вызовы других методов на основе в этом состоянии. Задачи должны время от времени отказываться от управления, чтобы это работало, потому что это определение «совместной многозадачности». Это также причина, по которой все современные операционные системы не используют совместную многозадачность.
Эта реализация не (1) не следует честному планированию (возможно, хранит промежуточное количество тактов, потраченных в методе run () задачи, и пропускает задачи, которые использовали слишком много времени относительно других, пока другие задачи не "перехватят") вверх "), (2) разрешить удаление задач или даже (3) разрешить остановку планировщика.
Что касается связи между задачами, вы можете рассмотреть вопрос о libtask Plan 9 или newsqueak Роба Пайка для вдохновения (загрузка "Реализация Newsqueak в UNIX" включает в себя статью "The Реализация "Newsqueak", в которой обсуждается передача сообщений на интересующей виртуальной машине).
Но я считаю, что это основной скелет, который имел в виду Страуструп.