Изящно (то есть в конечном итоге совместно) приостановить выполнение потока - PullRequest
1 голос
/ 10 февраля 2011

Мне нужно разработать приложение, которое пытается эмулировать поток выполнения встроенной цели. Эта цель имеет 2 уровня приоритета: самый высокий из них имеет приоритет над самым низким. Низкий уровень приоритета управляется с помощью циклического планировщика, который дает 1 мс выполнения каждому потоку по очереди.

Моя цель - написать библиотеку, которая будет предоставлять thread_create, thread_start и все системные вызовы, доступные на моей цели, и использовать функции POSIX для естественного воспроизведения поведения на стандартном ПК.
Таким образом, когда выполняется поток с высоким приоритетом, потоки с низким приоритетом должны быть приостановлены независимо от того, что они делают в этот самый момент. Ответственность за реализацию потока с низким приоритетом состоит в том, чтобы гарантировать, что он не будет нарушен.

Теперь приостановить поток обычно небезопасно, что объясняет, почему я не нашел никакой функции "suspend (pid)".

Я в основном представляю два решения проблемы:
- найти способ приостановить потоки с низким приоритетом при запуске потока с высоким приоритетом (и возобновить их, когда больше нет действий с высоким приоритетом)
- периодически вызывать очень маленькую функцию «suspend_if_needed» в моем низкоприоритетном коде, и всякий раз, когда должен запускаться высокоприоритетный процесс, дождаться, пока весь низкоприоритетный процесс вызовет эту функцию и будет приостановлен, выполнить как единый высокоприоритетный поток, а затем возобновить их всех.

Даже если это не так чисто, мне очень нравится второе решение, но все же есть одна проблема: как вызвать функцию везде, не меняя весь мой код? Интересно, есть ли простой способ сделать это, что-то вроде отладочного кода: добавить вызов ловушки на каждую выполняемую строку, которая проверяет флаг, и запускать определенный код при изменении этого флага?

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

Заранее спасибо,

Goulou.

Ответы [ 2 ]

1 голос
/ 10 февраля 2011

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

Если вы хотите реализовать систему с приоритетом потоков в чистом POSIX, один из вариантов: не использовать потоки, а вместо этого использовать setcontext для совместной многозадачности. Это позволит вам переключаться между потоками на уровне пользователя. Однако в этом случае вы должны явно указать процессор. Это также не помогает при блокировке системных вызовов, которые затем блокируют все потоки в вашем приложении; но поскольку вы пишете эмулятор, это может не быть проблемой.

Вы можете также иметь возможность менять потоки, используя setcontext в обработчике сигналов; Я сам не проверял этот случай, но стоит попробовать составить расписание с использованием setcontext в обработчике SIGALRM.

0 голосов
/ 14 апреля 2011

Чтобы приостановить поток, вы спите. Если вы хотите иметь возможность разбудить его по команде, переведите его в режим сна sigwait , который переводит поток в спящий режим до тех пор, пока он не получит сигнал. Вы можете послать определенному потоку сигнал с помощью pthread_kill (сумасшедшее имя, но на самом деле он просто отправляет сигналы в поток). Это очень быстрый способ спать и просыпаться. В 40 раз быстрее, чем условные переменные, и очень просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...