far2l icon indicating copy to clipboard operation
far2l copied to clipboard

многопоточная работа

Open ctapmex opened this issue 4 months ago • 1 comments

Пытаюсь прикрутить многопочтоку в colorer в рамках far. И столкнулся с взаимной блокировкой, которую не понимаю как обойти.

мой код тут https://github.com/ctapmex/far2l/tree/thread . всё крутится вокруг https://github.com/ctapmex/far2l/blob/thread/colorer/src/pcolorer2/ColorerWorker.cpp . изменений на 3 коммита, можно глянуть. сама раскраска еще не работает, там отрабатывается логика передачи/получения данных между потоками на примитивах.

логика работы следующая

  1. при открытии редактора запускается отдельный поток из ColorerWorker
  2. потоку дается задание обработать строки
  3. поток обращается за строкой в буфер. если в буфере её нет, то вызывается Info.AdvControl(Info.ModuleNumber, ACTL_SYNCHRO, &cmd, nullptr); , который в последствии передает управление плагину в основном потоке Far. плагин получив команду делает push массива строк в сторону потока.
  4. когда поток обработал нужное число строк, отображаемое сейчас в редакторе, он через Info.AdvControl(Info.ModuleNumber, ACTL_SYNCHRO, &cmd, nullptr); посылает команду, что надо отрисовать.

и всё работает более или менее нормально. данные гуляют как надо. Но проблема возникает при закрытии редактора, когда ловим взаимную блокировку.

функция Info.AdvControl в отличии от far3 обернута в "многопоточку". Она не отработает пока не освободится мютекс основного потока. и мы получаем следующее

  1. основной поток фара работает, и вызывает colorer с командой закрытия редактора. мютекс фара заблокирован, обработка идет в плагине.
  2. в это время поток смотрит, что строки кончились и вызывает AdvControl, и встает на ожидание мютекса , заблокированного в пункте 1 . так же в функции получения этих строк взведен мютекс потока, чтобы никто не вклинился.
  3. в рамках обработки закрытия редактора colorer вызывает деструктор , в рамках которого пытается остановить поток предварительно захватив его мютекс.
  4. в итоге два потока ждут друг друга

пока не понимаю как победить. под far3 не пробовал еще, но если там нет мютексов на AdvControl, то проблемы быть не должно.

ctapmex avatar Aug 24 '25 11:08 ctapmex

спасибо @shmuz , подсказал попробовать AdvControlAsync. пока полет нормальный. issue пока не закрываю, вдруг еще вопросы будут

ctapmex avatar Aug 24 '25 17:08 ctapmex