【发布时间】:2016-02-25 18:35:18
【问题描述】:
我正在使用 Qt 和 C++ 进行项目,并且项目使用多线程和外部全局变量。 extern 变量正在从不同的线程访问以进行读取和写入,因为当前没有实现互斥锁来读取/写入这些变量。现在我在运行程序时遇到了一些异常,这不是每次都发生,而是随机发生。
这些是 Qtcreator 的一些输出
Invalid address specified to RtlValidateHeap( 000000778A310000, 000000778E6AF5D0 )
Debug Assertion Failed!
Program: ...AppStore-MSVC_X64\debug\App.exe
File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointer(pUserData)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
Debug Assertion Failed!
Program: ...AppStore-MSVC_X64\debug\App.exe
File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1328
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
这是异常后的截图。
- 这是因为 extern 变量不是线程安全的吗?
- 或者由于变量未初始化,但在调试时我可以看到变量有一些数据。
编辑
由于项目包含大量源代码,我无法在此处发布整个代码,但情况类似于
global.h
extern QString outfilepath;
main.cpp
QString outfilepath;
...................
...................
outfilepath = somePath;
thread1.cpp
...................
QString tmp1 = outfilepath;
...................
thread2.cpp
...................
QString tmp2 = outfilepath;
...................
【问题讨论】:
-
让我们变得真实:您正在显示 4 个语句,没有上下文,并希望我们找出问题所在?它会飞的情况很少。假装显示的代码不是你的,而是我的。你能帮助我吗?没有。因此,请帮助我们通过显示重现问题的最小、自包含测试用例来帮助您。通过制作这样的测试用例,您将学到很多东西。首先复制您的项目并开始扔掉东西。删除不会使问题消失的每个声明和声明都应该删除。
-
我的直觉是你知道的不够多,无法正确实现多线程,但不可能知道你到底不知道什么:(
-
可能的错误源数量是天文数字。
outfilepath可能已被流氓指针或溢出破坏。但是,我们可以排除忍者。 -
@Kuba Ober 查看我的编辑。我只想知道从没有互斥锁的不同线程访问外部变量会导致这样的异常吗?。
-
@Harris 只要您保证在其他线程访问它之前已经设置了字符串的值,并且只要您保证不会更改字符串的值,它就不会引起问题。理想情况下,您希望
outfilepath成为const QString,并且线程在其构建后启动。
标签: c++ multithreading qt