2013-05-21 3 views
0

У меня есть процесс P и поток ядра KT. Я хочу синхронизировать выполнение P с KT. KT - это в основном обработчик событий. Но мое требование состоит в том, что KT не должен продолжать обработку событий, если P запущен. Поэтому мне нужно приостановить P, а затем продолжить обработку событий в KT и возобновить P. Итак, мой вопрос: от KT, как я могу принудительно вытеснить P? Для возобновления позже я могу просто использовать wake_up_process().Как вытеснить один процесс из другого процесса/потока ядра?

Для планирования процесса обычно используется трюк, чтобы установить состояние как TASK_INTERRUPTIBLE и расписание вызовов(). Будет ли он работать, если у меня есть указатель task_struct из P, а затем из KT, чтобы запланировать P, я устанавливаю состояние P (вместо текущего) как TASK_INTERRUPTIBLE и расписание вызовов? Это хак, не так ли? Вы видите какой-то чистый способ, которого мне не хватает?

Есть ли какой-нибудь сигнал, который я могу отправить P, чтобы попросить его упредить?

+2

Если требуется синхронизация, почему бы не использовать примитив синхронизации (например, futex) вместо некоторых неясных трюков? Имейте блок процесса и разбудите его, когда есть что обработать. – Damon

+0

'SIGSTOP' (так как вы просили сигналы) схож - зачем применять такой взлом? Использование нескольких потоков подразумевает параллелизм (в действительности это не имеет особого смысла), если потоки только запускаются исключительно, вы можете использовать один поток для всего). Итак, пусть блок потребляющих потоков (приложений) на futex или на eventfd (через epoll, если хотите), и продюсер (поток ядра) сообщают, что когда что-то нужно делать. Это гораздо меньше, чем склонность к провалу. – Damon

+0

Спасибо Дэймон. Я переработал, чтобы использовать блокировки вместо взлома. – spa

ответ

1

Вы не можете делать то, что вы просите. Конечно, вы можете установить состояние TASK_INTERRUPTIBLE из другого процесса/потока, выполняющегося на том же или на другом процессоре/ядре. Но вы не можете вызывать расписание() на другом CPU/core (по той же причине вы не можете вызывать любую другую функцию на другом CPU/ядре). Считайте, что schedule() не принимает идентификатор CPU/core ID в качестве аргумента, так как бы вы сказали, что core1 должен перепланировать?

Другим популярным решением этих требований синхронизации является использование приоритетов в реальном времени. Это почти так же уродливо, как и то, что вы предложили, но на самом деле может работать , если у вас есть ядро, поддерживающее приоритеты в реальном времени. Идея здесь проста, процесс P имеет более высокий приоритет, чем KT, и он будет вытеснять KT, когда он будет готов к запуску. Используйте привязку к процессору, чтобы заставить оба процесса работать на одном CPU/ядре (это важно, иначе это не сработает). Кстати, в этом подходе нет никакой реальной синхронизации: вы строго полагаетесь на приоритеты RT для обеспечения соблюдения, когда P и KT выполняются по отношению друг к другу.

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

+1

Если вы не можете удаленно разбудить поток, ожидающий события, это будет означать, что поток, оставляющий мьютекс, который ждет другой поток, не может разбудить ожидающий поток, но, конечно, он делает (и ожидающий поток doesn ' t дождитесь окончания следующего таймера таймера, чтобы начать выполнение). Как это могло тогда работать? – BeeOnRope

+0

@BeeOnRope - вы не можете использовать мьютексы для сигнализации о событии (см. [Здесь] (https://stackoverflow.com/questions/12551341/when-is-a-condition-variable-needed-isnt-a-mutex -enough/12569318 # 12569318)), но вы _can_ используете переменную условия, которая включает мьютекс, но также использует уведомление о событии в форме семафора. И да, вы можете удаленно разбудить поток, но с мьютексами, семафорами и переменными состояния это не ** вы **, который планирует поток, _ the kernel is_! Использование примитивов потоков потоков и ядра для синхронизации потоков обречено на провал. Это была моя точка зрения. – slowjelj

+0

Я имею в виду, что код на одном ядре запускает код на другом ядре _all time_. Например, когда поток выходит из 'mutex', а другой поток ожидает этого мьютекса, этот« другой поток »обычно запускается на _another_ core (поскольку код, который только что оставил мьютекс, все еще работает на его ядре).Я не знаю, почему вы ссылаетесь на события или переменную условия: я просто выбрал мьютекс как самый простой пример объекта управления параллелизмом, то же самое относится к семафорам, барьерам, переменным условий. – BeeOnRope

Смежные вопросы