_adopt_thread

提供: RAD Studio
移動先: 案内検索

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++

+