Чтобы получить подробную информацию, используйте источник! Но это то, о чем я помню, когда читал ...
Существует два способа, по которым можно планировать потоки пользовательского уровня: добровольно и упреждающе.
- добровольного планирования: потоки должны вызвать функцию периодически, чтобы передать использование CPU другому потоку. Эта функция называется
yield()
или schedule()
или что-то в этом роде.
- Предварительное планирование: библиотека принудительно удаляет процессор из одного потока и передает его другому. Обычно это делается с помощью сигналов таймера, таких как
SIGALARM
(подробнее см. man ualarm
).
О том, как сделать настоящий переключатель, если ваша ОС дружественна и обеспечивает необходимые функции, это легко. В Linux у вас есть функции makecontext()
/swapcontext()
, которые облегчают обмен данными между одной задачей. Опять же, см. Страницы руководства для деталей.
К сожалению, эти функции удалены из POSIX, поэтому другие UNIX могут не иметь их. Если это так, есть и другие трюки, которые можно сделать. Самым популярным был тот, кто вызывал sigaltstack()
, чтобы настроить альтернативный стек для управления сигналами, а затем kill()
сам, чтобы перейти в альтернативный стек, и longjmp()
от сигнальной функции до фактического потока пользовательского режима, который вы хотите запустить. Умный, мм?
В качестве примечания стороны в потоках пользовательского режима Windows называются волокнами и также полностью поддерживаются (см. Документы от CreateFiber()
).
Последнее средство использует ассемблер, который может работать почти везде, но он полностью зависит от конкретной системы. Шаги по созданию UMT будут следующими:
- Выделить стек.
- Выделить и инициализировать контекст UMT: структуру для хранения значений соответствующих регистров процессора.
и переключаться с одного УМТ к другому:
- Сохранить текущий контекст.
- Переключите стопку.
- Восстановите следующий контекст в CPU и перейдите к следующей инструкции.
Эти шаги относительно просты в использовании ассемблером, но совершенно невозможны в обычном C без поддержки каких-либо трюков, упомянутых выше.