Потоки застряли в boost :: unique_lock из-за сигнала в реальном времени - PullRequest
0 голосов
/ 10 октября 2019

У меня многопоточный процесс, из которого два потока (T1, T2) используют сигнал в реальном времени (SIGRTMIN), чтобы планировать определенный набор задач для других потоков, скажем, каждые 20 мсек. Только T1 планирует задачу, T2 не выполняет ничего, кроме как вернуться в цикл. Кроме того, значение PR процесса - это rt.

 //T1
int result  = sigwait(sigset_test, &sig)
if (result == 0)
{
      Log(LOG_DEBUG, string("Updating other thread"));
      //enqueues tasks to other threads
      PostUpdateToOtherThreads();
}

 //T2
 while(1)
 {
     int sig;
     int result = sigwait(signal_set, &sig)
     if (shutdown)
         break;
 }

реализация функции Log () выглядит примерно так:

void Log(int loglevel, string s)
{
     boost::shared_lock<boost::shared_mutex> Lock(Lock_);
     //log stuff to stream or file based log level
}

Другие потоки вызывают функцию Log для регистрации. Есть другой поток, скажем, T4, который обновляет уровень журнала, используя unique_lock. Только этому потоку разрешено обновлять уровни журнала,

void UpdateLogLevel(int newLevel)
{
 //exclusive access to shared mutex. other threads calling the 
 //Log function would block until this is complete
 boost::unique_lock<boost::shared_mutex> WriteLock(Lock_); 
 //update log level, also do some more stuff like log rotate etc.
}

Проблема заключается в том, что, когда T4 выполняет больше функций в функции UpdateLogLevel, поток T1 получает сигналы RT, что приводит к его бесконечной блокировке, что происходит другими потоками. вид застревания, так как они зависят от функции PostUpdateToOtherThreads (). Этого не происходит, если общее время, проведенное T4 в UpdateLogLevel, составляет менее 20 мс (т. Е. Длительность сигнала RT). затраченное время велико, тогда потоки как бы застревают, и единственный способ восстановить процесс - убить его или прервать.

Обходной путь для исправления заключается в том, чтобы поток T1 вообще не вызывал функцию Log, но я не мог найти лучший способ исправить это. С точки зрения сигнала, если T1 блокируется, пока сигналы RT ожидают в очереди, всякий раз, когда освобождается unique_lock, поток начинает возвращать ожидающий сигнал и должен возобновить работу. sigwait определяет поведение, но мне не совсем ясно, что будет происходить. Если

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