Поэтому я пытаюсь использовать mutex_init()
, mutex_lock()
, mutex_unlock()
для синхронизации потоков.
В настоящее время я пытаюсь планировать потоки в режиме циклического перебора (но более 1 потока можетзапускаться одновременно), и я устанавливаю текущее состояние потока на TASK_INTERRUPTIBLE
, после чего просыпается другой поток, чей PID у меня есть в списке.
Мне нужно перебрать этот список для своей логики.
Насколько я понимаю, мне нужно заблокировать этот список при доступе к его элементам, иначе другой поток может пропустить новую запись, пока яВношу изменения в нее.Кроме того, поскольку один мьютекс заблокировал ресурс, никакой другой мьютекс не сможет разблокировать его, пока оригинальный мьютекс не освободит его.
Но я все еще не уверен, правильно ли я его блокирую.(Я снимаю блокировку перед вызовом schedule()
и снова блокирую после этого)
Я объявляю мьютекс локально в потоке и блокирую список.После того, как мой текущий поток блокирует
mutex_lock(&lock);
, и я перебираю список, пока не найду что-то (или не завершу, если ничего не найду), затем разблокирует.
mutex_unlock(&lock);
IПредположим, блокировка, пока я повторяю, является законнойХотя я никогда не видел примеров этого.
Кроме того, нормально ли, что процесс имеет состояние (TASK_UNINTERRUPTIBLE
), пока он удерживает блокировку мьютекса?
EDIT: Я добавляю еще немного информации, основываясь на ответе ниже.
Возможно, моя программа может быть запущена на виртуальной машине с одним ядром.Поэтому я не хочу рисковать бесконечным опросом, используя spin_lock()
.
Я пытаюсь сохранить планирование между потоками, которые имеют определенный идентификатор.Например, если есть 4 темы.2 в наборе «A» и 2 в наборе «B».Я разрешаю запускать только 1 поток в каждом наборе.Но я переключаюсь между потоками в данном наборе.Тем не менее, поток в наборе 'A' не должен переключаться на какой-либо поток в наборе 'B'
(я знаю, что планировщик ядра не будет идеальным, так что приблизительное переключение подойдет).
Мое обоснование для TASK_STATE:
1) Работает начальный созданный поток.
2) Если работает другой поток в том же наборе (и этот не выполнялся в течение заданного времени).Установите для другого потока значение TASK_INTERRUPTIPLE
при вызове schedule()
; Примечание: В каждом наборе может быть более 2 потоков, но давайте сделаем все просто, рассматривая пока только 2.
3) Если это выполнено в течение достаточного времени, поставьте эту задачуна TASK_INTERRUPTIPLE
, установите другую задачу в том же наборе на TASK_RUNNING
, при этом вызывая schedule()
;
Вся эта логика происходит, когда я обращаюсь к определенным структурам данных, которые заблокированы (теперь) Globalмьютекс.Я разблокирую мьютекс как раз перед тем, как позвонить schedule()
, и сразу после этого снова блокирую.После того, как моя логическая часть закончена, я полностью разблокирую мьютекс.
Что-то принципиально не так с подходом?