_adopt_thread
Process.h:インデックス への移動
ヘッダー ファイル
process.h
カテゴリ
プロセス制御ルーチン
プロトタイプ
_PTHREAD_ADOPTION_DATA _adopt_thread(void (_USERENTRY *__start_address)(void *), void * __arglist, int free_flag );
説明
(Windows API CreateThread 関数で作成された)スレッドを、必要な内部データ(例外、スタック情報など)をフックアップすることで、C++Builder RTL に「導入(Adopt)」します。その結果、_adopt_thread によって RTL は、そのスレッド内で発生した例外を処理できるようになります。このスレッドの実行パスは、そこから、別の関数(アダプティブ スレッド関数)へと転送されます。RTL の側からは、このアダプティブ スレッド関数の実行の間、スレッドは、_beginthreadex への呼び出しによって作成されたように見え、他の RTL 関数の呼び出しや、例外の送出/補足など、すべての利点を享受できます。
スレッドを作成するには、ユーザーは通常通り _beginthread を呼び出します。これが、自動的に内部データをフックアップします。_adopt_thread はまずこの内部データが存在しなかった場合に使用されます。たとえば、これは、ユーザーが、ISAPI など、外部ソースからのスレッドから呼び出された際に発生します。
_adopt_thread を使用すると、C++Builder でコンパイルした DLL を C++Builder 以外の EXE から使用できます。_adopt_thread 次によって動作します:
- ユーザー関数を呼び出す(arglist パラメータで渡す)
- 例外情報のフックを解除する
- ハンドルをスレッド コンテキストに返す
この処理により、同じ関数を再び使用することができます(すべてのデータを再度割り当てなくても)。このサイクルの最後で、_unadopt_thread 関数を呼び出して、この残りのデータを最終的に解放することができます。
最後のパラメータ、free_flag では、スレッド データ構造体を、関数の終了時に解放するかを決定します:
- free_flag が 0 の場合、アダプティブ関数が終了した際に、例外ハンドラがフック解除されるのみとなります。スレッドの導入の間に割り当てられたRTL 固有データの残りは、有効なままです。その後、同じスレッドが _adopt_thread を再び呼び出すと、既存のデータが使用され、例外ハンドラが再度フックされ、指定されたアダプティブスレッド関数が呼び出されます。
- free_flag が 0 以外に設定された場合、スレッド データ構造体は、_adopt_thread が返る前に解放されます。この場合、返されたスレッド ハンドルは NULL です。これは関連付けられているデータがすでに解放されているためです。
戻り値
__free_flag パラメータが false(0)の場合、_adopt_thread はハンドル(スレッド コンテキスト)を返すので、後ほどそれを _unadopt_thread() に渡すことで、これらのデータ構造体をを解放することができます。
_adopt_thread への __free_flag パラメータが 0 以外だった場合、スレッド データは _adopt_thread が返る前に解放されるため、返されるハンドルは NULL となります。
エラーが発生した場合、errno は次に設定されます:
ENOMEM - メモリが不十分です
例
#include <process.h>
#include <windows.h>
void adopted_thread(void*)
{
printf("Running in a RTL-managed thread!\n");
}
unsigned long __stdcall winapi_thread(void*)
{
/*
This code runs on another thread, created by CreateThread Win32 API.
_adopt_thread is used to continue the execution in the routine that
is RTL managed (in the same thread context).
*/
printf("Running in a simple thread! Adopting ...\n");
''_PTHREAD_ADOPTION_DATA'' data = '''_adopt_thread'''(adopted_thread, NULL, false);
/* Un-adopt the thread and release it's resources */
printf("Back to OS thread! Release adoption ...\n");
_unadopt_thread(data);
}
int _tmain(int argc, _TCHAR* argv[])
{
/* Create a thread using OS APIs, thus RTL-unmanaged */
unsigned long threadId;
CreateThread(NULL, 0, winapi_thread, NULL, 0, &threadId);
Sleep(100);
return 0;
}
移植性
POSIX | Win32 | ANSI C | ANSI C++ |
---|---|---|---|
+ |