我尝试使用多线程允许两个任务在一个DLL中并行运行,但我的应用程序一直在崩溃,显然是由于一些糟糕的资源冲突管理;这是详细信息: 我需要从主逻辑流的某个点调用相同的函数(DoGATrainAndRun),为其中一个参数传递一个不同的值,让两个参数运行,然后返回主逻辑流程,并使用两个(不同的) )2次调用返回的值集。
(这是在主头文件中):
typedef struct
{
int PredictorId;
int OutputType;
int Delta;
int Scale;
int Debug;
FILE* LogFile;
int TotalBars;
double CBaseVal;
double* HVal;
int PredictionLen;
double*** Forecast;
} t;
(这是主要的逻辑流程):
hRunMutex=CreateMutex(NULL, FALSE, NULL);
arg->OutputType=FH;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
arg->OutputType=FL;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
do {} while (hRunMutex!=0);
CloseHandle(hRunMutex);
(这是在DoGaTrainAndRun的最后):
free(args);
ReleaseMutex( hRunMutex );
我对多线程很陌生,我似乎无法想出这一点......
答案 0 :(得分:0)
还有一些事情:
首先,您将相同的结构传递到两个线程中,但只是更改OutputType
值。如果可能,第一个帖子会看到FL
,但永远不会看到值FH
。原因是如何安排线程。它对您的第一个线程有效,然后被暂停。然后,您的主线程创建第二个线程,将OutputType
设置为FL
。该线程启动,第一个线程也恢复。但是,第一个现在将OutputType
视为FL
。
接下来,两个线程都使用相同的结构,但其中一个线程正在释放内存。如果另一个线程在其他版本之后仍在使用它,那么您将在仍在使用它的线程中获得未定义的行为。这可能会导致崩溃。
您尝试等待线程退出是错误的。你不需要互斥锁,你当然不需要旋转它来测试零。只需使用WaitForMultipleObjects:
HANDLE handles[2];
handles[0] = (HANDLE)_beginthread(...);
handles[1] = (HANDLE)_beginthread(...);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
这将阻止主线程在浪费cpu周期时旋转。当等待返回时,您将知道两个线程都已完成。
把这些放在一起应该给你这样的东西:
HANDLE handles[2];
t *arg1=malloc(sizeof(t));
arg1->OutputType=FH
handles[0] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg1);
t *arg2=malloc(sizeof(t));
arg2->OutputType=FL
handles[1] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg2);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
free(arg1);
free(arg2)
并且不要在DoGATrainAndRun
中释放任何记忆。