我刚刚在我的项目中使用Intel Parallel inspector,它会显示警告:
应用程序中的一个或多个线程访问另一个线程的堆栈 线。这可能表示您的应用程序中存在一个或多个错误。
我确实有一些在线程之间共享的堆栈上分配的对象。我不明白为什么这是一个问题。任何提示?
答案 0 :(得分:10)
这不是错误,它可能是错的。像英特尔Parallel Inspector这样为程序提供额外诊断的工具必须在误报和漏报之间进行权衡,在这种情况下,开发人员认为访问另一个线程的堆栈更可能是一个错误(低如果报告,则报告假阳性率(如果没有报告,则为高假阴性率)。
Valgrind是另一个可以在代码中发出错误信号的工具示例。
这里真正的问题是,“其他线程在做什么?”如果您认为“也许它将从该函数返回并且堆栈帧将无效”,那么您正在进行错误的并行编程。没有关于多线程行为的答案应该用“maybe”来限定。你最好确保该线程不会返回,例如,让它等待信号量或条件变量,或者让它与其他线程连接。
Pubby:“AFAIK非常低效。”
效率低下的唯一原因是因为您可能有多个核心修改相同的缓存行,这与其他类型的共享内存存在同样的问题。
Collin:你怎么知道另一个线程中的堆栈帧仍然很好?
如果在多个线程中使用某些东西,则使用某种同步机制来确保它不会以无效方式进行修改。这种情况也不例外。
H2CO3:嗯,你有没有理由不能走进另一个人的家?
如果我们打算玩类比,我会说这个过程就是房子,每个线程都是房子里的人。如果Dave在他的房间里保留了一份家务清单,每次我需要查看清单时,我都会进入他的房间。如果他停止这样做,他最好告诉我,否则我会开始在他的桌子上随意写一些纸。
这种程序行为是否可以接受是一种风格问题。
答案 1 :(得分:4)
想象一下 - 线程正在执行,并且调用了一个具有本地(堆栈)变量(对象)的方法。它将此对象添加到工作队列中,该队列由单独的线程处理。
该线程获取第一个线程添加的项目并访问第一个线程的堆栈上的对象。
同时完成第一个主题是什么?它可能已经退出该方法并释放了该堆栈空间。释放的空间可能会也可能不会被重复使用。访问第一个线程堆栈的第二个线程可能会或可能不会正常工作,具体取决于时间和调用图。
如果您知道堆栈变量将在第二个线程处理它时存在,那么它可以安全地执行;例如,如果线程1对堆栈变量进行排队,然后阻塞,直到线程2通知它已完成处理,这是一个安全的操作。
发出警告而不是错误,因为这可能是合法的操作,也可能不是,并且分析仪无法确定。