0

マルチスレッドを利用するプログラムを書くために書いています。マルチスレッドについて調べてみたところ、サンプル プログラムを動作させることができました。しかし、私はグリッチに遭遇し、何が問題なのかわかりません。サンプル プログラムを投稿しており、問題が発生している場所を強調しています。

#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(&current_time);
        cout << ctime(&current_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(&current_time);
        cout << ctime(&current_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つのファイルを出力できるようにするために何をする必要があるかを知りたいです

前もって感謝します

4

0 に答える 0