Как сделать поток в C без использования библиотеки POSIX [закрыто]


Я хочу реализовать многопоточность в C без использования какой-либо библиотеки POSIX. Любая помощь будет оценена по достоинству.

Not: Не используйте fork() или vfork ().

4 8

4 ответа:

См.:

Для UNIX-подобных систем.

Также смотрите:

Для BSD и современных UNIXes.

Эта страница дает много примеров реализаций barebone, использующих эти примитивы и многое другое.

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

Я также предлагаю посмотреть на фактические реализации библиотек потоков userland, чтобы получить некоторые подсказки. Смотрите эту страницу, на которой приведен список реализаций для Linux.

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

Поток в Linux-это, по сути, процесс, которыйсовместно использует память и ресурсы со своим родителем. Ядро Linux не делаетразличия между процессом и потоком, другими словами, нет понятия легкого процессав Linux, как и в некоторых других операционных системах. Потоки в Linux реализуются как стандартные процессы, поэтому можно создать поток, используя только clone(), который обычно вызывается fork() следующим образом способ:

clone(SIGCHLD, 0);

Это клонирует только обработчики сигналов, однако с соответствующими флагами вы можете создать поток:

clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);
Это идентично предыдущему вызову, за исключением того, что адресное пространство, ресурсы файловой системы, файловые дескрипторы и обработчики сигналов совместно используются двумя процессами.

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

Проверьтеclone(2) man page для получения подробной информации, и если вы хотите получить дополнительную информацию, я рекомендую Linux Kernel Development 3rd edition by Robert Love, (не связан с автор в любом случае) есть взгляд внутри ссылки там вы могли бы прочитать некоторые из них в интернете. Что касается потоков пользовательского уровня, то есть минимальный пакет, написанный мной, называемый libutask, который реализует как кооперативный, так и упреждающий планировщик, вы можете проверить исходный код, если хотите.

Примечание 1: я не упоминал UNIX, насколько мне известно, это специфичная для Linux реализация.

примечание 2: Создание собственных потоков с помощью clone не является реальным решением, прочитайте комментарии к некоторым проблемам, с которыми вам, возможно, придется иметь дело, это только ответ на вопрос, Можно ли создавать потоки без использования pthreads, в этом случае ответ-да.

Вы также можете проверить новый заголовок <threads.h> из стандартной библиотеки C. (C11)

В нем есть то, что вам нужно, например int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);, а также функции мьютекса и переменные условия.

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

Если разрешено прерывание таймера с обратным вызовом, можно выполнить упреждающее действие. микроядро.

По крайней мере, доктор Доббс и IOCCC представили варианты в этом направлении.