У меня многопоточный процесс, из которого два потока (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 определяет поведение, но мне не совсем ясно, что будет происходить. Если