多线程 C 应用程序中的访问冲突

发布于 2024-10-18 12:02:03 字数 2257 浏览 2 评论 0原文

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

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

THREADFUNCS.H

#ifndef _threadfuncs_h
#define _threadfuncs_h 

#include <windows.h>

extern DWORD WINAPI ThreadA(LPVOID params);

#endif

THREADFUNCS.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;
}

谢谢。

I'm trying to write a simple C application that is multithreaded. I want the main thread to be suspended until some flag is set by the worker thread. So for my thread function param I pass a struct that includes the flag. When I assign the flag in the worker thread, I get an access violation. I am using a Mutex to theoretically prevent simultaneous access to this struct instance that is being shared between the main app and the worker thread. Can someone point me in the right direction? The full project code is below. I have denoted the error line in comments in the THREADFUNCS.C file.

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

THREADFUNCS.H

#ifndef _threadfuncs_h
#define _threadfuncs_h 

#include <windows.h>

extern DWORD WINAPI ThreadA(LPVOID params);

#endif

THREADFUNCS.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;
}

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

雨轻弹 2024-10-25 12:02:03

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

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

You need to create the mutex before you create the thread.

Right now your thread will WaitForSingleObject on an invalid handle

梦屿孤独相伴 2024-10-25 12:02:03

参数&r应该是CreateThread调用中的第四个参数。它当前为 0(空),当您在线程函数中取消引用该指针时,这会导致访问冲突。

The parameter &r should be the 4th parameter in the CreateThread call. It is currently 0 (null), which would cause an access violation when you dereference the pointer in the thread function.

日久见人心 2024-10-25 12:02:03

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

在 globals.h 中:

extern HANDLE ghMutex;

在 main.c 中:

HANDLE ghMutex = 0;

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

You have multiple static variables called ghMutex (one in main.c, one in threadfuncs.c). You should combine these into a single mutex, then initialise it before you create the new thread.

in globals.h:

extern HANDLE ghMutex;

in main.c:

HANDLE ghMutex = 0;

In main.c move the mutex initialisation before the thread is created.

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