我面临同步主线程和信号处理程序之一的问题。
让我们考虑一下简单的课程:
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方法中完成工作的通知->通过选择函数接收该通知,超时并可以继续进行...但是,例如,如果该线程(threadId)处于不间断状态,该怎么办?
我不会输入signalHandler方法,select()方法将收到超时,但是应用程序将在PrintBactrace方法中结束返回空向量堆栈的工作,并且我们不知道该线程是否不会更改其状态,因此当其他进程获得StackPrinter类的实例并尝试引发另一个信号时,signalHandler方法将最终执行。因此最后,当第一个进程仍想使用_backtrace数组时,另一个进程将使用_backtrace数组。
请记住,signalHandler方法中使用的所有内容都必须是异步信号安全(http://man7.org/linux/man-pages/man7/signal-safety.7.html)。
编辑: 有一会儿我有了一个静态映射的想法,其中键是线程,值可以是向量。 因此,我将裁撤void ** backtrace并将其粘贴到signalHandler函数中,所以它的唯一工作就是获取backtrace并将其放置在map中。如果它将在正常时间结束,则主线程将从映射中获取此向量-如果没有,则永远不会获得此数据。假设这种情况很少见,则不会有过多使用内存的风险。你觉得呢?