_beginthreadNT

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Process.h - Index


Header-Datei

process.h

Kategorie

Prozesssteuerungsroutinen

Prototyp

unsigned long _beginthreadNT(void (_USERENTRY *start_address)(void *), unsigned stack_size, void *arglist, void *security_attrib, unsigned long create_flags, unsigned long *thread_id);

Beschreibung

Startet die Ausführung eines neuen Thread unter Windows NT.

Anmerkung:  Der Parameter start_address muss als _USERENTRY deklariert werden.

Alle Windows NT-Multithread-Programme müssen statt der Thread-erstellenden API-Funktion des Betriebssystems entweder _beginthreadNT oder _beginthread verwendet werden, weil diese Funktionen die Initialisierung durchführen, die für die korrekte Arbeitsweise der Laufzeit-Bibliotheksfunktionen erforderlich ist. Die Funktion _beginthreadNT unterstützt die Sicherheitsfunktionen des Betriebssystems. Diese Funktionen sind nur in den Multithread-Bibliotheken verfügbar.

Die Funktion _beginthreadNT erstellt und startet einen neuen Thread. Der Thread beginnt die Ausführung bei start_address. Wenn Ihr Thread endet, wird automatisch die Funktion _endthread aufgerufen. _endthread schließt das Thread-Handle und ruft die API-Funktion ExitThread auf.

Die Größe seines Stack in Bytes ist stack_size; der Stack wird von dem Betriebssystem zugewiesen, nachdem die Stack-Größe auf das nächste Mehrfache von 4096 aufgerundet wurde. Der Parameter arglist des Threads kann NULL sein, muss aber angegeben werden.

Die Funktion _beginthreadNT verwendet den Zeiger security_attr für den Zugriff auf die SECURITY_ATTRIBUTES-Struktur. Die Struktur enthält die Sicherheitsattribute für den Thread. Ist security_attr NULL, wird der Thread mit den Standardsicherheitsattributen erstellt. Das Thread-Handle wird nicht geerbt, wenn security_attr gleich NULL ist.

_beginthreadNT untersucht die Variable create_flags nach Flags, die zusätzliche Informationen zur Erstellung des Thread liefern. Diese Variable kann den Wert Null enthalten, der anzeigt, dass der Thread unmittelbar nach seiner Erstellung ausgeführt wird. Die Variable kann auch den Wert CREATE_SUSPENDED enthalten; in diesem Fall wird der Thread erst nach einem Aufruf der Funktion ResumeThread ausgeführt. ResumeThread ist eine Win32-API-Funktion.

_beginthreadNT initialisiert die Variable thread_id mit der Thread-ID.

Rückgabewert

Bei erfolgreicher Ausführung gibt _beginthreadNT das Handle des neuen Threads zurück. Der Rückgabewert ist ein Standard-Windows-Handle, das für die API-Funktionen des Betriebssystems, etwa SuspendThread und ResumeThread verwendet werden kann.

Bei einem Fehler gibt die Funktion -1 zurück, und die globale Variable errno wird auf einen der folgenden Werte gesetzt:

EAGAIN

Too many threads (Zu viele Threads)

EINVAL

Invalid stack size (Ungültige Stack-Größe, also weniger als 16 Byte oder Null)

ENOMEM

Not enough memory (Unzureichend Speicher)


Siehe auch die Beschreibung der Win32-API-Funktion GetLastError in der MSDN-Dokumentation.

Beispiel

/*  Verwenden Sie für dieses Beispiel die Kommandozeilenoption -tWM  (32-Bit Multi-Thread-Ziel)  */
#pragma checkoption -tWM
#include <windows.h>
#include <process.h>
#include <stdio.h>
#define NTHREADS 25
static LONG runningThreads = 0;
static HANDLE doneEvent;
/* Diese Funktion fungiert als die Funktion 'main' für jeden neuen Thread */
static void threadMain(void *arg)
{
  printf("Thread %2d has an ID of %u\n", (int)arg, GetCurrentThreadId());
  /* InterlockedDecrement() verwenden, um die globale Variable runningThreads auf
 * thread-sichere Weise zu ändern.  Wenn der Zähler 0 erreicht, den Haupt-Thread fragen,
 * ob er für uns ein Ereignis erstellt hat.
 */
  if (InterlockedDecrement(&runningThreads) == 0 && doneEvent)
      SetEvent(doneEvent);
}
int main(void)
{
   HANDLE hThreads[NTHREADS];
   int i;
   DWORD  threadId;
   SECURITY_ATTRIBUTES  sa = {
          sizeof(SECURITY_ATTRIBUTES), /* Strukturgröße */
          0,      /* Kein Sicherheitsdeskriptor */
          TRUE    /* Thread-Handle ist vererbbar */
   };
   /* NTHREADS vererbbare Threads erstellen, die zunächst ausgesetzt sind und die beginnend mit threadMain() ausgeführt werden */
   for(i = 0; i < NTHREADS; i++) {
      hThreads[i] = (HANDLE)_beginthreadNT(
         threadMain,   /* Thread-Startadresse */
         4096,         /* Thread-Stack-Größe */
         (void *)i,    /* Thread-Startargument */
         &sa,          /* Thread-Sicherheit */
         CREATE_SUSPENDED,  /* Erstellung im ausgesetzten Zustand */
         &threadId);   /* Thread-ID */
      if(hThreads[i] == INVALID_HANDLE_VALUE) {
         MessageBox(0, "Thread Creation Failed", "Error", MB_OK);
         return  1;
      }
      ++runningThreads;
      printf("Created thread %2d with an ID of %u\n", i, threadId);
   }
   printf("\nPress ENTER to thaw all threads\n\n");
   getchar();
   /* Das Ereignis erstellen, das anzeigt, dass alle Threads beendet sind */
   doneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
 
   /* Zurückgestellte Threads wieder aufnehmen */
   for(i = 0; i < NTHREADS; i++)
      ResumeThread(hThreads[i]);
   /* Wenn möglich, auf das Ausführungsende aller Threads warten */
   if (doneEvent) {
     WaitForSingleObject(doneEvent, INFINITE);
     CloseHandle(doneEvent);
   }
   return 0;
}

Portabilität

POSIX Win32 ANSI C ANSI C++

+