互斥锁示例中未处理的异常/访问冲突写入位置

发布于 2024-11-06 13:49:41 字数 1486 浏览 6 评论 0原文

我正在研究使用互斥体保护全局双精度的示例,但是我收到错误 -

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

属性 2024-11-13 13:49:41

代码中的剩余错误在于对 WaitForMultipleObjects() 的调用。您将第三个参数设置为 0 (FALSE),这样只要 10 个线程中的任何一个完成,主线程就会解除阻塞。

这会导致对 DeleteCriticalSection() 的调用在所有线程完成之前执行,从而在(可能)其他 9 个线程之一启动并调用 EnterCriticalSection() 时产生访问冲突。

The remaining bug in your code is in the call to WaitForMultipleObjects(). You set the 3rd parameter to 0 (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 calls EnterCriticalSection().

戏蝶舞 2024-11-13 13:49:41

您的写入超出了 threads[10] 数组的末尾:

for (int loop = 0; loop < 1000; loop++){
     threads[loop];
}

threads 的大小只有 10!

You're writing beyond the end of your threads[10] array:

for (int loop = 0; loop < 1000; loop++){
     threads[loop];
}

threads only has size 10!

两相知 2024-11-13 13:49:41

您的问题是 WaitForMultipleObjects 没有等待所有线程完成,导致临界区被过早删除。根据 MSDN,第三个参数是

bWaitAll [中]

如果此参数为 TRUE,则当发出 >lpHandles 数组中所有对象的状态信号时,该函数返回。如果为 FALSE,则当任一对象的状态设置为有信号时,该函数返回。在后一种情况下,返回值指示对象 > 其状态导致函数返回。

您将其设置为 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

bWaitAll [in]

If this parameter is TRUE, the function returns when the state of all objects in the >lpHandles array is signaled. If FALSE, the function returns when the state of any one of >the objects is set to signaled. In the latter case, the return value indicates the object >whose state caused the function to return.

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.

轮廓§ 2024-11-13 13:49:41

您还应该将分数声明为易失性的,这样就不会出现缓存值问题。

You should also declare score as a volatile so you don't have cached value problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文