线程是否有理由不能访问其他线程的堆栈?

Vio*_*ffe 8 c++ multithreading

我刚刚在我的项目中使用Intel Parallel inspector,它会显示一条警告:

应用程序中的一个或多个线程访问另一个线程的堆栈.这可能表示您的应用程序中存在一个或多个错误.

我确实有一些在线程之间共享的堆栈上分配的对象.我不明白为什么这是一个问题.任何提示?

Die*_*Epp 10

这不是错,这只是可能是错误的.像英特尔Parallel Inspector这样为程序提供额外诊断的工具必须在误报和漏报之间进行权衡,在这种情况下,开发人员认为访问另一个线程的堆栈更可能是一个错误(低报告的假阳性率比否(如果没有报告,则为高假阴性率).

Valgrind是另一个可以在代码中发出错误信号的工具示例.

这里真正的问题是,"其他线程在做什么?" 如果您认为"也许它将从该函数返回并且堆栈帧将无效",那么您正在进行错误的并行编程.没有关于多线程行为的答案应该用"maybe"来限定.最好确保该线程不返回,例如,使其等待信号量或条件变量,或者使其与其他线程连接.

讨论

Pubby: "AFAIK非常低效."

效率低下的唯一原因是因为您可能有多个内核修改相同的缓存行,这与其他类型的共享内存存在同样的问题.

Collin:你怎么知道堆栈帧在另一个线程中仍然很好?

如果在多个线程中使用某些东西,则使用某种同步机制来确保它不会以无效方式进行修改.这种情况也不例外.

H2CO3:嗯,你不应该走进另一个人的房子吗?

如果我们要玩类比,我会说这个过程就是房子,每个线程都是房子里的人.如果Dave在他的房间里保留了一份家务清单,每次我需要查看清单时,我都会进入他的房间.如果他停止这样做,他最好告诉我,否则我会开始在桌子上随意写一些纸.

结论

这种程序行为是否可接受是一种风格问题.


Ste*_*n P 5

想象一下——一个线程正在执行,一个方法被调用,它有一个本地(堆栈)变量(一个对象)。它将这个对象添加到一个工作队列中,该队列由一个单独的线程处理。

该线程获取第一个线程添加的项并访问第一个线程的堆栈上的对象。

在此期间第一个线程做了什么?它可能已退出该方法并释放该堆栈空间。释放的空间可能会或可能不会被重新使用。第二个线程访问第一个线程的堆栈可能会也可能不会正常工作,具体取决于时间和调用图。

如果您知道堆栈变量在第二个线程处理它时将存在,那么这样做是安全的;例如,如果线程 1 将堆栈变量排队,然后阻塞直到线程 2 通知它已完成处理,则这是一个安全操作。

发出警告而不是错误是因为这可能是也可能不是合法操作,并且分析器无法确定。