_adopt_thread

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu process.h - Index


Header-Datei

process.h

Kategorie

Prozesssteuerungsroutinen

Prototyp

_PTHREAD_ADOPTION_DATA _adopt_thread(void (_USERENTRY *__start_address)(void *), void * __arglist, int free_flag );

Beschreibung

"Adoptiert" einen mit der Windows API-Funktion CreateThread erzeugten Thread für die C++Builder-RTL, indem sie sich in die notwendigen internen Daten (Exceptions, Stack-Informationen usw.) einhängt. _adopt_thread ermöglicht es der RTL dadurch, Exceptions dieses Threads zu behandeln. Der Ausführungspfad dieses Threads wird dann an eine andere Funktion (der adoptierenden Thread-Funktion) übergeben. Aus der Perspektive der RTL erscheint der Thread während der Ausführung der adoptierenden Thread-Funktion so, als wäre er über einen Aufruf _beginthreadex erzeugt worden, und dem Thread werden entsprechende Rechte eingeräumt, etwa das Aufrufen anderer RTL-Funktionen sowie das Auslösen und Abfangen von Exceptions.

Normalerweise wird ein Thread durch den Aufruf von _beginthread erzeugt. Dabei werden die internen Daten automatisch übernommen. _adopt_thread wird vor allem in den Fällen verwendet, in denen diese internen Daten nicht vorhanden sind. Dies kann zum Beispiel dann vorkommen, wenn die Benutzerfunktion aus einem Thread einer externen Quelle, etwa ISAPI, aufgerufen wird.

Die Funktion _adopt_thread ermöglicht es außerdem, dass mit C++Builder kompilierte DLLs von nicht mit C++Builder erstellten EXE-Dateien verwendet werden. _adopt_thread führt Folgendes durch:

  • Aufruf der Benutzerfunktion (der der Parameter arglist übergeben wird)
  • Abkoppeln der Exception-Informationen
  • Rückgabe eines Handle für den Thread-Kontext

Dieser Prozess erlaubt, die gleiche Funktion erneut zu verwenden (ohne Neuzuweisung all dieser Daten). Am Ende des Zyklus kann die Funktion _unadopt_thread aufgerufen werden, um die restlichen Daten freizugeben.

Der letzte Parameter free_flag legt fest, ob beim Beenden der Funktion die Datenstrukturen des Threads freigegeben werden:

  • Hat free_flag den Wert Null, wird beim Beenden der adoptierenden Funktion nur der Exception-Handler freigegeben. Die restlichen RTL-spezifischen Daten, die während der Adoption des Thread zugewiesen wurden, bleiben gültig. Ruft der gleiche Thread dann _adopt_thread erneut auf, werden die vorhandenen Daten verwendet, der Exception-Handler erneut eingehängt, und die angegebene adoptierende Threadfunktion wird aufgerufen.
  • Hat free_flag einen Wert ungleich Null, werden die Datenstrukturen des Threads freigegeben, bevor _adopt_thread zurückkehrt. In diesem Fall ist das zurückgegebene Thread-Handle NULL, weil die mit ihm verknüpften Daten bereits freigegeben wurden.

Rückgabewert

Ist der Parameter __free_flag false (0), gibt _adopt_thread ein Handle (Thread-Kontext) zurück, das später zur Freigabe dieser Datenstrukturen verwendet werden kann, indem es _unadopt_thread() übergeben wird.

Hat der Parameter __free_flag von _adopt_thread einen Wert ungleich Null, werden die Thread-Daten freigegeben, bevor _adopt_thread zurückkehrt, und das zurückgegebene Handle ist NULL.

Ist ein Fehler aufgetreten, wird errno folgender Wert zugewiesen:

ENOMEM Not enough memory (Unzureichend Speicher)

Beispiel

#include <process.h>
#include <windows.h>
void adopted_thread(void*)
 {
   printf("Wird in einem RTL-verwalteten Thread ausgeführt!\n");
 }
 
 unsigned long __stdcall winapi_thread(void*)
 {
   /*
    Dieser Code wird auf einem anderen Thread ausgeführt, der von CreateThread-Win-32 erstellt wurde.
    _adopt_thread wird verwendet, um die Ausführung in der RTL-verwalteten 
    Routine fortzusetzen (in dem selben Thread-Kontext).
   */
   printf("Wird in einem einfachen Thread ausgeführt! Anpassen von ...\n");
   ''_PTHREAD_ADOPTION_DATA'' data = '''_adopt_thread'''(adopted_thread, NULL, false);
 
   /* Gibt den Thread und dessen Ressourcen frei. */
   printf("Zurück zum OS-Thread! Geben Sie die Adoption frei ...\n");
   _unadopt_thread(data);
 }
 
 int _tmain(int argc, _TCHAR* argv[])
 {
   /* Einen Thread mit Hilfe der APIs des Betriebssystems und nicht mit Hilfe von RTL erstellen */
   unsigned long threadId;
   CreateThread(NULL, 0, winapi_thread, NULL, 0, &threadId);
 
   Sleep(100);
 
   return 0;
 }

Portabilität

POSIX Win32 ANSI C ANSI C++

+