【问题标题】:Access Violation In Multithreaded C Application多线程 C 应用程序中的访问冲突
【发布时间】:2011-02-22 15:21:07
【问题描述】:

我正在尝试编写一个简单的多线程 C 应用程序。我希望主线程被挂起,直到工作线程设置了某个标志。因此,对于我的线程函数参数,我传递了一个包含标志的结构。当我在工作线程中分配标志时,我遇到了访问冲突。我正在使用 Mutex 从理论上防止同时访问在主应用程序和工作线程之间共享的这个结构实例。有人可以指出我正确的方向吗?完整的项目代码如下。我已经在 THREADFUNCS.C 文件中的 cmets 中指出了错误行。

GLOBALS.H

#ifndef _globals_h
#define _globals_h

#include <windows.h>


static HANDLE ghMutex;


#endif

THREADCOM.H

#ifndef _threadcom_h
#define _threadcom_h

typedef struct { 
   char bContinueMain;
} RComData;

#endif

线程函数.H

#ifndef _threadfuncs_h
#define _threadfuncs_h 

#include <windows.h>

extern DWORD WINAPI ThreadA(LPVOID params);

#endif

线程函数.C

#include <stdio.h>
#include "threadcom.h"
#include "threadfuncs.h"
#include "globals.h"

DWORD WINAPI ThreadA(LPVOID params)
{
   RComData* pr = (RComData*)params;
   int i;

   printf("You are in thread A.\n");
   WaitForSingleObject(ghMutex, INFINITE);
   pr->bContinueMain = TRUE; /* ACCESS VIOLATION HERE */
   ReleaseMutex(ghMutex);
   for (i=0; i<10; ++i)
   {
      printf("Printing THREAD A line %i.\n", i);
   }
}

MAIN.C

#include <windows.h>
#include <stdio.h>
#include "threadfuncs.h"
#include "threadcom.h"
#include "globals.h"

void WaitForGoAhead(RComData* pr)
{
   char bGo = FALSE;
   while (!bGo)
   {
      WaitForSingleObject(ghMutex, INFINITE);
      if (pr->bContinueMain)
         bGo = TRUE;
      ReleaseMutex(ghMutex);
   }
}

int main(void)
{
   int i;
   HANDLE hThreadId = -1;
   RComData r = { FALSE };

   hThreadId = CreateThread(0, 0, ThreadA, 0, &r, &hThreadId);
   WaitForSingleObject(hThreadId, 1);
   if (hThreadId > 0)
   {
      printf("Thread has been launched.\n");
      ghMutex = CreateMutex(0, FALSE, 0);
      WaitForGoAhead(&r);
      for (i=0; i<10; ++i)
      {
         printf("Printing main proc line %i.\n", i);
      }
      WaitForSingleObject(hThreadId, INFINITE);
      printf("Thread is complete.\n");
      CloseHandle(ghMutex);
      CloseHandle(hThreadId);
   }
   else
   {
      printf("Thread failed to created.\n");
   }

   printf("Press any key to exit...");
   getchar();
   return 0;
}

谢谢。

【问题讨论】:

  • 谁使用互斥锁来实现这种锁?你肯定想要一个关键部分吗?
  • 那么这就是我要研究的东西。问题是我已经在 .NET 领域生活了太久,现在我正试图倒退并学习做所有事情的艰难方法:-)
  • 在单个进程中,Critical Section 比 Mutex 好得多。更容易使用,更快等。它们都是一般意义上的互斥锁,互斥,一次拥有一个对象。我最近写了一个关于关键部分的详细答案:stackoverflow.com/questions/5054114/how-to-create-locks-in-vc

标签: c multithreading winapi mutex access-violation


【解决方案1】:

您需要在创建线程之前创建互斥锁

现在您的线程将 WaitForSingleObject 处理无效句柄

【讨论】:

    【解决方案2】:

    参数&amp;r 应该是CreateThread 调用中的第4 个参数。当前为 0(null),当你在线程函数中取消引用指针时会导致访问冲突。

    【讨论】:

    • +1:正确回答了 OP 的问题,而不是我的回答处理另一个错误。
    • @Eric - 尽管如此,您的回答涵盖了可以说是更微妙的问题:)。 +1
    • 谢谢。不知道我是怎么错过的。
    【解决方案3】:

    您有多个名为 ghMutex 的静态变量(一个在 main.c 中,一个在 threadfuncs.c 中)。您应该将它们组合成一个互斥体,然后在创建新线程之前对其进行初始化。

    在 globals.h 中:

    extern HANDLE ghMutex;
    

    在 main.c 中:

    HANDLE ghMutex = 0;
    

    在 main.c 中,在创建线程之前移动互斥体初始化。

    【讨论】:

    • 噢,开枪。我又回到了那里的 C# 习惯。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    相关资源
    最近更新 更多