1

解決済み: mingw 4.6.2から4.7.0にアップグレードしましたが、完全に機能します。これは単なるバグだったと思います。

私はマルチスレッドアプリケーションを適切に終了する方法についていくつかの調査を開始し、他のスレッドに終了を通知するために使用する方法についての2つの投稿(最初2番目)を見つけました。QueueUserAPC

試してみる必要があると思いましたが、APCProcから例外をスローすると、アプリケーションがクラッシュし続けます。

コード:

#include <stdio.h>
#include <windows.h>

class ExitException
{
public:
    char *desc;
    DWORD exit_code;

    ExitException(char *desc,int exit_code): desc(desc), exit_code(exit_code)
    {}
};

//I use this class to check if objects are deconstructed upon termination
class Test 
{
public:
    char *s;

    Test(char *s): s(s)
    {
        printf("%s ctor\n",s);
    }

    ~Test()
    {
        printf("%s dctor\n",s);
    }
};

DWORD CALLBACK ThreadProc(void *useless)
{
    try
    {
        Test t("thread_test");

        SleepEx(INFINITE,true);

        return 0;
    }
    catch (ExitException &e)
    {
        printf("Thread exits\n%s %lu",e.desc,e.exit_code);
        return e.exit_code;
    }
}

void CALLBACK exit_apc_proc(ULONG_PTR param)
{
    puts("In APCProc");
    ExitException e("Application exit signal!",1);
    throw e;

    return;
}

int main()
{
    HANDLE thread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL);

    Sleep(1000);

    QueueUserAPC(exit_apc_proc,thread,0);

    WaitForSingleObject(thread,INFINITE);

    puts("main: bye");

    return 0;
}

私の質問は、なぜこれが起こるのかということです。

コンパイルにmingwを使用しており、OSは64ビットです。

これが理由でしょうか?QueueApcProc64ビットプロセスで実行されるスレッドを32ビットアプリから呼び出すべきではない、またはその逆を行うべきではないことを読みましたが、そうではないはずです。

編集:これをVisualStudioのc++コンパイラ2010でコンパイルしましたが、問題なく動作しました。これはgcc / mingwのバグである可能性がありますか?

4

1 に答える 1

1

VS2005でも同じことが再現できました。問題は、コンパイラがcatch離れて最適化することです。なんで?C++ 標準によれば、extern "C"関数が例外で終了した場合に何が起こるかは定義されていないためです。SleepExしたがって、コンパイラは(これはextern "C") がスローされないと想定します。のインライン化の後Test::Test、どちらもスローされないTest::~Testことがわかり、その結果、このブロック内の何かが例外を介して終了した場合printf

    Test t("thread_test");

    SleepEx(INFINITE,true);

    return 0;

動作は未定義です!

/EHscMSVC では、コードはRelease ビルドのスイッチでは機能しませんが、/EHaまたは/EHsで機能します。これにより、C 関数がスローされる可能性があると想定するように指示されます。おそらくGCCにも同様のフラグがあります。

于 2012-06-23T15:12:36.693 に答える