<Низкоуровневый C, специфичный для Linux> Необходимо выполнить переход сигнала на метку вместо выполнения вызова функцииLinux

Ответить
Anonymous
 <Низкоуровневый C, специфичный для Linux> Необходимо выполнить переход сигнала на метку вместо выполнения вызова функции

Сообщение Anonymous »

Я пишу программу на C, в которой мне приходится периодически (каждую секунду) выполнять множество задач. Доступных потоков ЦП может быть меньше, чем количество задач. Я могу просто создать отдельный поток для каждой задачи, но... мы учимся, переусердствуя с чем-то, и поэтому я хочу сделать задержку как можно меньшей и сэкономить циклы процессора. Это предполагает ручное вытесняющее планирование.
У меня будет очередь задач в глобальной памяти, расположенная в порядке возрастания их приоритета. Каждый поток захватит задачу для выполнения (атомарно синхронизированный поток). Как только задача потребует приостановки до следующего интервала, мы начнем выполнять другие задачи. Функция main будет периодически выдавать сигнал всем потокам, указывая, что началась (или запустится) новая секунда и все задачи необходимо перевыполнить от высшего к низшему приоритету. Каждый поток получит сигнал, а ядро ​​переключит контекст на обработчик сигнала. Все наши задачи представляют собой сопрограммы без стека, управляемые операторами переключения и вручную увеличивающие переменную в каждом блоке кода, поэтому не имеет значения, прерываются ли они на уровне инструкций, поскольку этот выход может быть запущен снова (будет обеспечивать асинхронную безопасность). Теперь в обработчике сигнала мы можем начать перезапускать задачи в соответствии с их приоритетом. Если все задачи завершены до следующего интервала, все потоки спят до доставки сигнала.
Если один поток возобновляет задачу, наполовину выполненную другим потоком, нам потребуется перенести локальное хранилище. Все это создает копию хранилища всех задач в стеке каждого потока. Мы могли бы прикрепить к цепочке только избранные задачи, но это противоречит всей цели. Есть ли способ освободить память стека потока после полного выполнения задачи?
Я использую сигналы, потому что они обеспечивают асинхронное прерывание. Что-то вроде timerfd или signalfd требует опроса, которого я хочу избежать.
У этого подхода есть несколько проблем. Обратите внимание, что я не использовал технические термины, такие как функции и указатели на функции. Если бы я использовал функции, они никогда бы не возвращались. Продолжая переключаться между различными функциями, мы продолжаем создавать новые кадры стека. По сути, я никогда не смогу вызвать функцию задачи. Что мы можем использовать, так это просто операторы goto и указатели меток для прямого перехода к инструкциям задачи.
Теперь проблема, с которой я столкнулся, заключается в том, что когда поток получает сигнал, ядро ​​принудительно переключает контекст, сохраняя состояние процессора в стеке, а также вызывая функцию обработчика сигнала, которая также попадает в стек. Но если в функции обработчика сигнала я собираюсь перейти оттуда к блоку кода и никогда не возвращаться, стек будет продолжать накапливаться. Обычно, как только мы выходим из функции-обработчика, ядро ​​снова переключает контекст, восстанавливая регистры ЦП, и выполнение начинается с того места, где оно было первоначально. Это то, что я знаю и могу ошибаться. Но здесь мы никогда не выходим из функции-обработчика. Поскольку наши задачи представляют собой сопрограммы без стека, мне даже не нужно сохранять состояние процессора.
Поэтому по сути я хочу перейти к метке вместо вызова функции в качестве обработчика сигнала.

Подробнее здесь: https://stackoverflow.com/questions/798 ... tead-of-pe
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»