8

Linux (PThreads を使用) と Windows (組み込みの WinThreads を使用) の両方に C++ ライブラリを作成しています。これは、任意のプログラムにアタッチでき、スレッドの終了時に関数を呼び出す必要があります。プロセス。

私は pthreads の pthread_cleanup_push と pthread_cleanup_pop を知っていますが、これらは別の字句スコープを追加するマクロであるため、私には機能しませんが、ライブラリが初めて呼び出されたときにこの関数を宣言し、プログラム自体を実行できるようにしたいのですが独自のコードですが、必要があります。Windowsで同様のものはまったく見つかりませんでした。

これは、スレッドが停止したときに外部スレッドにアラートを出すことを意味するわけではないことに注意してください。また、プログラム自体によって制御されているため、スレッドが終了する方法を変更できるという意味でもありません。乗るために。

したがって、問題は次のとおりです。この場合、スレッドがどのように作成または破棄されるかを制御できない場合、Windows または Linux のいずれかで、スレッドが閉じたときに呼び出される関数を作成するための最良の方法は何ですか? ?

たとえば、メインプログラムでは次のようになります。

void* threadFunc(void* arg)
{
    printf("Hello world!\n");
    return NULL;
}

int main(int argc, char** argv)
{
    int        numThreads = 1;
    pid_t*     pids       = NULL;
    pids     = (pid_t*)     calloc(sizeof(pid_t), numThreads);

    pthread_create(&ntid, NULL, threadFunc, &nVal);
    pthreads[0] = ntid;

    pthread_join(pthreads[0], NULL);
    return 0;
}

ライブラリ内:

void callMeOnExit()
{
    printf("Exiting Thread!\n");
}

スレッドが return NULL; に達したときに callMeOnExit が呼び出されるようにしたいと思います。この場合、メイン スレッドが return 0; に達したときと同様です。pthread_exit をラップすることは他のケースでも機能し、解決策になる可能性がありますが、可能であればより良い方法が必要です。

どうすればこれを行うことができるかについて誰かがアイデアを持っているなら、それは素晴らしいことです!

4

4 に答える 4

7

そのため、いくつかのコード レビューの後、Linux でこれを行うためのはるかに洗練された方法を見つけることができました。これは、Windows がファイバーで行うこと (Neeraj が指摘するように) と、調べ始めたときに期待していたことの両方に一致します。この問題。

重要なのは、pthread_key_createが 2 番目の引数として、この TLS データを初期化したスレッドが終了したときに呼び出されるデストラクタへのポインタを受け取ることです。スレッドごとに別の場所で TLS を既に使用していましたが、TLS への単純なストアにより、この機能も取得され、確実に呼び出されるようになります。

于 2012-05-22T19:31:23.257 に答える
4

これを変える:

pthread_create(&ntid, NULL, threadFunc, &nVal);

の中へ:

struct exitInformData
{
   void* (CB*)(void*);
   void* data;
   exitInformData(void* (cp*)(void*), void* dp): CB(cp) data(dp) {}
};
pthread_create(&ntid, NULL, exitInform, new exitInformData(&threadFunc, &nVal));

それから加えて:

void* exitInform(void* data)
{
    exitInformData* ei = reinterpret_cast<exitInformData*>(data);

    void* r = (ei.CB)(ei.data);   // Calls the function you want.
    callMeOnExit();               // Calls the exit notification.
    delete ei;
    return r;
}
于 2012-04-30T23:14:32.683 に答える
3

Windows の場合、Fls Callbacksを試すことができます。これらの FLS システムを使用して、スレッドごとにストレージを割り当てることができます (「ファイバー」部分は無視してください。各スレッドには 1 つのファイバーが含まれます)。このコールバックを取得してストレージを解放しますが、コールバックで他のことも実行できます。

于 2012-05-05T17:43:14.220 に答える
0

これはすでに尋ねられていることがわかりましたが、そのときに与えられた解決策はあなたが望むものと同じではないかもしれません...

別のアイデアとしては、単純に pthread_t クラス/構造体から拡張し、pthread_exit 呼び出しをオーバーライドして、必要に応じて別の関数を呼び出してから、スーパークラス pthread_exit を呼び出すことです。

于 2012-04-30T22:06:12.113 に答える