マルチスレッドを利用するプログラムを書くために書いています。マルチスレッドについて調べてみたところ、サンプル プログラムを動作させることができました。しかし、私はグリッチに遭遇し、何が問題なのかわかりません。サンプル プログラムを投稿しており、問題が発生している場所を強調しています。
#include <Windows.h>
#include <process.h>
#include <iostream>
#include <cassert>
#include <ctime>
#import "calc.dll" \
auto_rename no_namespace no_smart_pointers \
raw_native_types named_guids
using namespace std;
HANDLE th_mutex;
struct Arguments
{
string case_id;
string file;
};
//____________________________________
unsigned int __stdcall TestThread(void *args)
{
int i = 0,
j = 0;
cout << "Inside thread" << endl;
for (i = 0; i <= 10000; i++)
{
for (j = 0; j <= 100000; j++)
{
}
if (i == 10000)
cout << "The value of i inside the thread = " << i << endl;
}
return EXIT_SUCCESS;
}
//____________________________________
unsigned int __stdcall Thread(void *args)
{
CoInitialize(0);
{
Arguments *input;
input = (Arguments *) args;
time_t current_time;
time(¤t_time);
cout << ctime(¤t_time) << endl;
IHeatExchangerNetwork *hxNetwork = 0;
IDispatchPtr theUnit = 0;
IHeatTransferUnit *unit = 0;
VARIANT vAppend;
_bstr_t filename,
output;
filename = input->file.c_str();
filename += input->case_id.c_str();
filename += ".dat";
output = input->file.c_str();
output += input->case_id.c_str();
output += ".dbo";
cout << filename << endl;
cout << output << endl;
HRESULT hr = CoCreateInstance(CLSID_HeatExchangerNetwork,
0,
CLSCTX_ALL,
DIID_IHeatExchangerNetwork,
reinterpret_cast<void**>(&hxNetwork));
theUnit = hxNetwork->LoadHeatTransferUnit(filename, HxUnitTypeKey::HxUnitTypeCrossflow);
hr = theUnit->QueryInterface(DIID_IHeatTransferUnit, reinterpret_cast<void**>(&unit));
hxNetwork->Run(0, 0);
vAppend.boolVal = false;
unit->WriteDBOFile(output, OutputData, vAppend);
time(¤t_time);
cout << ctime(¤t_time) << endl;
}
CoUninitialize();
return EXIT_SUCCESS;
}
//____________________________________
int main()
{
DWORD retval;
Arguments args[2];
args[0].case_id = "1";
args[0].file = "C:\\Documents and Settings\\User\\My Documents\\Test Cases\\1\\";
args[1].case_id = "2";
args[1].file = "C:\\Documents and Settings\\User\\My Documents\\Test Cases\\2\\";
th_mutex = CreateMutex(NULL, FALSE, NULL);
if (th_mutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 1;
}
// ================================
// Basic testing of calling threads
// ================================
HANDLE hnd1;
cout << "Before creating new thread" << endl;
hnd1 = (HANDLE) _beginthreadex(NULL, 0, &TestThread, NULL, 0, 0);
cout << "After creating thread" << endl;
// ====================================
// Calling Calc routine through threads
// ====================================
HANDLE hnd2,
hnd3;
hnd2 = (HANDLE) _beginthreadex(NULL,
0,
&Thread,
(void *)&args[0],
0,
0);
hnd3 = (HANDLE) _beginthreadex(NULL,
0,
&Thread,
(void *)&args[1],
0,
0);
WaitForSingleObject(hnd1, INFINITE);
WaitForSingleObject(hnd2, INFINITE);
WaitForSingleObject(hnd3, INFINITE);
GetExitCodeThread(hnd1, &retval); // Gets the return value from the function
CloseHandle(hnd1);
CloseHandle(hnd2);
CloseHandle(hnd3);
return EXIT_SUCCESS;
}
私が直面している問題は、プログラムを実行すると次の出力が得られることです
Before creating new thread
After creating threadInside thread
Thu Aug 09 10:56:58 2012
Thu Aug 09 10:56:58 2012
C:\Documents and Settings\User\My Documents\Test Cases\1\1.datC:\Documents and Settings\User
\My Documents\Test Cases\2\2.dat
C:\Documents and Settings\kcomandur\My Documents\Test Cases\1\1.dboC:\Documents and Settings\User
\My Documents\Test Cases\2\2.dbo
The value of i inside the thread = 10000
Thu Aug 09 10:57:08 2012
その後、プログラムがクラッシュします。次のエラーが表示されます
Debug Error!
Program: ...MultiThreading.exe
R6010
-abort() has been called
(Press Retry to debug the application)
再試行すると、_com_dispatch_method で始まる次の場所にある生成された .tli ファイルで中断が発生します。
#pragma implementation_key(723)
inline IDispatch * IHeatExchangerNetwork::LoadHeatTransferUnit ( BSTR filename, enum HxUnitTypeKey unitType ) {
IDispatch * _result = 0;
_com_dispatch_method(this, 0x20, DISPATCH_METHOD, VT_DISPATCH, (void*)&_result,
L"\x0008\x0003", filename, unitType);
return _result;
}
ファイル名変数の値は
C:\Documents and Settings\User\My Documents\Test Cases\2\2.dat
ミューテックスを使ってみて、スレッド関数を修正しました
unsigned int __stdcall Thread(void *args)
{
CoInitialize(0);
{
WaitForSingleObject(th_mutex, INFINITE);
// Same content as original Thread function.
// Not writing it again to minimize space
ReleaseMutex(th_mutex);
}
CoUninitialize();
return EXIT_SUCCESS;
}
//____________________________________
今回は、.tli ファイルの次の場所 _com_dispatch_method でプログラムがクラッシュします。
#pragma implementation_key(966)
inline long IHeatTransferUnit::WriteDBOFile ( BSTR filename, short io, const VARIANT & vAppend ) {
long _result = 0;
_com_dispatch_method(this, 0x32, DISPATCH_METHOD, VT_I4, (void*)&_result,
L"\x0008\x0002\x080c", filename, io, &vAppend);
return _result;
}
ミューテックスを使用すると、HANDLE hnd3 を持つスレッドによってエラーが生成されます。変数 filename の値は
C:\Documents and Settings\User\My Documents\Test Cases\2\2.dbo
また、ミューテックスを使用することで、以前のエラーの場所を乗り越えることができました。
次の呼び出しのようにミューテックスが本当に必要かどうかはわかりません
hxNetwork->Run(0, 0);
互いに関係のない 2 つの異なるファイルで動作します。また、これはプログラムの中で最も時間がかかる部分であるため、2 つのケースを同時に実行したいと考えました。
私が行った方法でミューテックスを使用すると、最初のケースが実行され、次に 2 番目のケースが実行されます。
また、私は calc.dll を制御できません。これはサード パーティのソフトウェアであり、マルチスレッドをサポートしているかどうかはわかりません。
したがって、両方の実行を開始し、2つのファイルを出力できるようにするために何をする必要があるかを知りたいです
前もって感謝します