互斥锁示例中未处理的异常/访问冲突写入位置
我正在研究使用互斥体保护全局双精度的示例,但是我收到错误 -
0x77b6308e 处未处理的异常 Lab7.exe:0xC0000005:访问冲突 写入位置0x00000068。
我认为这与访问分数有关? (全局双精度)
#include <windows.h>
#include <iostream>
#include <process.h>
double score = 0.0;
HANDLE threads[10];
CRITICAL_SECTION score_mutex;
unsigned int __stdcall MyThread(void *data)
{
EnterCriticalSection(&score_mutex);
score = score + 1.0;
LeaveCriticalSection(&score_mutex);
return 0;
}
int main()
{
InitializeCriticalSection(&score_mutex);
for (int loop = 0; loop < 10; loop++)
{
threads[loop] = (HANDLE) _beginthreadex(NULL, 0, MyThread, NULL, 0, NULL);
}
WaitForMultipleObjects(10, threads, 0, INFINITE);
DeleteCriticalSection(&score_mutex);
std::cout << score;
while(true);
}
更新:
修复循环设置为 1000 而不是 10 的问题后,错误仍然发生,但是当我注释掉引用互斥体的代码片段时,错误发生了不会发生。
CRITICAL_SECTION score_mutex;
EnterCriticalSection(&score_mutex);
LeaveCriticalSection(&score_mutex);
InitializeCriticalSection(&score_mutex);
DeleteCriticalSection(&score_mutex);
更新2
线程按照约定返回0(这已经是漫长的一周了!)
我尝试添加回互斥相关的代码,程序将编译并运行良好(除了竞争条件问题)当然是双精度),并将 CRITICAL_SECTION、InitializeCriticalSection 和 DeleteCriticalSection 全部添加回来。问题似乎出在 EnterCriticalSection 或 LeaveCriticalSection 上,因为当我添加时错误再次出现 他们。
I'm working through an example of protecting a global double using mutexes, however I get the error -
Unhandled exception at 0x77b6308e in
Lab7.exe: 0xC0000005: Access violation
writing location 0x00000068.
I assume this is related to accessing score? (The global double)
#include <windows.h>
#include <iostream>
#include <process.h>
double score = 0.0;
HANDLE threads[10];
CRITICAL_SECTION score_mutex;
unsigned int __stdcall MyThread(void *data)
{
EnterCriticalSection(&score_mutex);
score = score + 1.0;
LeaveCriticalSection(&score_mutex);
return 0;
}
int main()
{
InitializeCriticalSection(&score_mutex);
for (int loop = 0; loop < 10; loop++)
{
threads[loop] = (HANDLE) _beginthreadex(NULL, 0, MyThread, NULL, 0, NULL);
}
WaitForMultipleObjects(10, threads, 0, INFINITE);
DeleteCriticalSection(&score_mutex);
std::cout << score;
while(true);
}
Update:
After fixing the problem with the loop being set to 1000 instead of 10, the error still occured, however when I commented out the pieces of code referring to the mutex the error did not occur.
CRITICAL_SECTION score_mutex;
EnterCriticalSection(&score_mutex);
LeaveCriticalSection(&score_mutex);
InitializeCriticalSection(&score_mutex);
DeleteCriticalSection(&score_mutex);
Update 2
The threads return 0 as per convention (It's been a long week!)
I tried adding back in the mutex-related code, and the program will compile and run fine (other than the race condition issues with the double of course) with CRITICAL_SECTION, InitializeCriticalSection and DeleteCriticalSection all added back in. The problem appears to be with EnterCriticalSection or LeaveCriticalSection, as the error reoccurs when I add them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
代码中的剩余错误在于对
WaitForMultipleObjects()
的调用。您将第三个参数设置为0
(FALSE
),这样只要 10 个线程中的任何一个完成,主线程就会解除阻塞。这会导致对
DeleteCriticalSection()
的调用在所有线程完成之前执行,从而在(可能)其他 9 个线程之一启动并调用EnterCriticalSection()
时产生访问冲突。The remaining bug in your code is in the call to
WaitForMultipleObjects()
. You set the 3rd parameter to0
(FALSE
) such that the main thread unblocks as soon as any of the 10 threads finishes.This causes the call to
DeleteCriticalSection()
to execute before all threads are finished, creating an access violation when one of the (possibly) 9 other threads starts and callsEnterCriticalSection()
.您的写入超出了
threads[10]
数组的末尾:threads
的大小只有 10!You're writing beyond the end of your
threads[10]
array:threads
only has size 10!您的问题是 WaitForMultipleObjects 没有等待所有线程完成,导致临界区被过早删除。根据 MSDN,第三个参数是
您将其设置为 0,当任何一个线程完成时都会返回。这会导致以下 DeleteCriticalSection 在仍有线程等待访问它时运行。
Your problem is that WaitForMultipleObjects is not waiting for all the threads to complete, causing the critical section to be prematurely deleted. According to MSDN, the third argument is
You set this to 0, which returns when ANY ONE of your threads completes. This causes the following DeleteCriticalSection to be run while there's still threads waiting to access it.
您还应该将分数声明为易失性的,这样就不会出现缓存值问题。
You should also declare score as a volatile so you don't have cached value problem.