У меня проблема с основным потоком синхронизации и обработчиком сигнала.
Давайте рассмотрим простой класс:
class StackPrinter
{
public:
StackPrinter* Instance()
{
// Implemented classic singleton
}
private:
std::vector<void*> PrintBacktrace(pthread_t threadId)
{
guard(someMutex);
std::vector<void*> stack;
_backtrace = &stack[0];
// set up signal
// kill thread so the signal will be raised
// synchronise this thread with signalHandler with select and read methods
return stack;
}
void** _backtrace;
void signalHander(int sigNumber)
{
backtrace(_backtrace);
// synchronise this thread with PrintBactrace with write method
}
}
Так что этот код обычно будет работать нормально: мы поднимаем сигнал,мы обрабатываем его в методе signalHandler -> уведомляем о завершении работы в методе signalHandler через функцию записи -> получаем это уведомление через функцию select с тайм-аутом и жизнь может продолжаться ... но что, если, например, этот поток (threadId) будет работать непрерывносостояние?
Я не буду вводить метод signalHandler, метод select () получит тайм-аут, но затем приложение завершит свою работу в методе PrintBactrace, возвращая пустой векторный стек, и мы не знаем, выиграл ли этот поток 'изменить его состояние, так что метод signalHandler будет выполнен в конце концов, когда, возможно, другой процесс получит экземпляр класса StackPrinter и попытается вызвать другой сигнал.Поэтому, наконец, другой процесс будет использовать массив _backtrace, когда первый все же захочет его использовать.
Пожалуйста, помните, что все, что используется в методе signalHandler, должно быть безопасным для асинхронного сигнала (http://man7.org/linux/man-pages/man7/signal-safety.7.html).
РЕДАКТИРОВАТЬ: На мгновение у меня возникла идея статической карты, где ключом будет поток, а значением может быть вектор. Поэтому я бы вырезал void ** backtrace и вставил его в функцию signalHandler, так что единственная работа с нимсостоит в том, чтобы получить обратную трассировку и поместить ее в карту. Если это закончится в обычное время, основной поток получит этот вектор с карты - если нет, никто никогда не получит эти данные. Предполагая, что эта ситуация редка, нет риска слишком большогоиспользованная память. Что вы думаете?