_beginthread, _beginthreadex

Cria um thread.

uintptr_t _beginthread( 
   void( *start_address )( void * ),
   unsigned stack_size,
   void *arglist 
);
uintptr_t _beginthreadex( 
   void *security,
   unsigned stack_size,
   unsigned ( *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr 
);

Parâmetros

  • start_address
    Inicie o endereço de uma rotina que iniciará a execução de uma nova thread.For _beginthread, é a convenção de chamada __cdecl ou __clrcall; para _beginthreadex, ele é __stdcall ou __clrcall.

  • stack_size
    dimensionar de pilha para um novo thread ou 0.

  • arglist
    Lista de argumentos que devem passar para um novo thread ou nulo.

  • security
    Ponteiro para um SECURITY_ATTRIBUTES estrutura que determina se o identificador retornado pode ser herdado pelos processos filhos.Se for nulo, o identificador não pode ser herdado.Deve ser nulo para Windows 95 aplicativos.

  • initflag
    Estado inicial de um novo thread (0 para executar ou CREATE_SUSPENDED para suspenso); use ResumeThread para o processo (thread).

  • thrdaddr
    Aponta para uma variável de 32 bit que recebe o identificador de thread.Pode ser NULL, caso em que ele não é usado.

Valor de retorno

Se bem-sucedida, cada uma dessas funções retorna um identificador para o segmento recém-criado; no entanto, se o thread recém-criado é encerrado muito rapidamente, _beginthread poderá não retornar um identificador válido (consulte a discussão na Remarks seção). _beginthread Retorna-1 L no erro, caso em que errno é conjunto para EAGAIN Se houver muitos segmentos para EINVAL Se o argumento é inválido ou o dimensionar da pilha for incorreto, ou para EACCES no caso de recursos insuficientes (sistema autônomo memória). _beginthreadex Retorna 0 em um erro, caso em que errno e _doserrno são definidas.

If startaddress é NULL, o manipulador de parâmetro inválido é chamado, conforme descrito em Validação de parâmetro. Se a execução for permitida para continuar, essas funções conjunto errno para EINVAL e retornar -1.

Para obter mais informações sobre esses e outros códigos de retorno, consulte _doserrno, errno, _sys_errlist e _sys_nerr.

Para obter mais informações sobre o uintptr_t, consulte Tipos padrão.

Comentários

The _beginthread função cria um thread que iniciará a execução de uma rotina no start_address. A rotina de start_address use o __cdecl convenção de chamada e não deve ter nenhum valor retornado. Quando o thread retorna dessa rotina, ela é encerrada automaticamente.Para obter mais informações sobre threads, consulte Multithreading.

_beginthreadex semelhante do Win32 CreateThread API mais próxima que _beginthread não. _beginthreadex é diferente de _beginthread das seguintes maneiras:

  • _beginthreadex tem três parâmetros adicionais: initflag, security, e threadaddr. O novo thread pode ser criado em um estado suspenso, com uma segurança especificado (somente Windows NT) e pode ser acessado usando thrdaddr, que é o identificador de thread.

  • A rotina de start_address passado para _beginthreadex use o __stdcall convenção de chamada e deve retornar um código de sair de thread.

  • _beginthreadex Retorna 0 falha, em vez de-1 L.

  • Um thread criado com _beginthreadex é terminada por uma telefonar para _endthreadex.

The _beginthreadex função lhe dá mais controle sobre como o segmento é criado de _beginthread não. The _endthreadex função também é mais flexível. Por exemplo, com _beginthreadex, você pode usar as informações de segurança, conjunto o estado inicial do segmento (executando ou suspenso) e obter o identificador de thread do thread recém-criado. Você também é capazes de usar o identificador de thread retornado por _beginthreadex com a sincronização de APIs, o que você não pode fazer com _beginthread.

É mais seguro usar _beginthreadex que _beginthread. Se o thread gerado por _beginthread sai rapidamente, o identificador retornado ao chamador de _beginthread pode ser inválido ou pior, aponte para outro thread. No entanto, o identificador retornado por _beginthreadex tem de ser fechado pelo chamador de _beginthreadex, para que ele é garantido que ser um identificador válido se _beginthreadex não retornou um erro.

Você pode telefonar _endthread or _endthreadex explicitamente para terminar um segmento; no entanto, _endthread ou _endthreadex ed telefonar automatitelefonary quando o thread retorna da rotina é passado sistema autônomo um parâmetro. Encerrando um thread com uma telefonar para endthread ou _endthreadex ajuda a garantir a recuperação adequada de recursos alocados para o thread.

_endthread Fecha automaticamente a thread manipular enquanto ( _endthreadex não). Portanto, ao usar _beginthread e _endthread, não fechar explicitamente o identificador de thread chamando do Win32 CloseHandle API.Esse comportamento é diferente do Win32 ExitThread API.

Observação:

Para um arquivo executável vinculadas com Libcmt.lib , não telefonar Win32 ExitThread API; isso evita que o em time de execução recursos alocados de sistema de recuperação. _endthread e _endthreadex recuperação thread recursos alocada e, em seguida telefonar ExitThread.

O sistema operacional controla a alocação da pilha quando qualquer um dos _beginthread ou _beginthreadex é chamado; você não precisa passar o endereço da pilha de thread para qualquer dessas funções. Além disso, a stack_size argumento pode ser 0, em que caso o sistema operacional usa o mesmo valor sistema autônomo a pilha especificada para o thread principal.

arglist é um parâmetro a serem passados para o recém-criado thread. Geralmente é o endereço de um item de dados, sistema autônomo uma seqüência de caractere.arglist pode ser NULL Se não for necessária, mas _beginthread e _beginthreadex deve ser fornecido com algum valor para passar para o novo thread. Todos os threads são encerrados se qualquer thread chama abort, exit, _exit, ou ExitProcess.

A localidade do novo thread é herdada do seu segmento pai.Se por thread local estiver habilitado por uma telefonar para _configthreadlocale (globalmente ou para novos threads somente), o thread pode alterar sua localidade independentemente de seu pai chamando setlocale ou _wsetlocale. Para obter mais informações, consulte Localidade.

Para misto e código puro, _beginthread e _beginthreadex ambos têm duas sobrecargas uma demorando um ponteiro de função nativa de convenção de chamada, Outros levando um __clrcall ponteiro de função. A primeira sobrecarga não é segura para domínio do aplicativo e nunca será ser.Se você estiver escrevendo código misto ou puro, você deve garantir que o novo thread entra o domínio do aplicativo correto antes que ele acesse recursos gerenciado.Você pode fazer isso, por exemplo, usando call_in_appdomain da função. A segunda sobrecarga é segura para domínio do aplicativo; o segmento recém-criado sempre acabará no domínio do aplicativo do chamador de _beginthread ou _beginthreadex.

Requisitos

Rotina

Cabeçalho necessário

_beginthread

<processo.h>

_beginthreadex

<processo.h>

Para obter mais informações de compatibilidade, consulte Compatibilidade na introdução.

Bibliotecas

Versões multithread do C em time de execução bibliotecas somente.

Para usar _beginthread ou _beginthreadex, o aplicativo deve vincular com uma das bibliotecas do time de execução C multithread.

Exemplo

O exemplo a seguir utiliza _beginthread e _endthread.

// crt_BEGTHRD.C
// compile with: /MT /D "_X86_" /c
// processor: x86
#include <windows.h>
#include <process.h>    /* _beginthread, _endthread */
#include <stddef.h>
#include <stdlib.h>
#include <conio.h>

void Bounce( void *ch );
void CheckKey( void *dummy );

/* GetRandom returns a random integer between min and max. */
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))

BOOL repeat = TRUE;     /* Global repeat flag and video variable */
HANDLE hStdOut;         /* Handle for console window */
CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */

int main()
{
    CHAR    ch = 'A';

    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );

    /* Get display screen's text row and column information. */
   GetConsoleScreenBufferInfo( hStdOut, &csbi );

    /* Launch CheckKey thread to check for terminating keystroke. */
    _beginthread( CheckKey, 0, NULL );

    /* Loop until CheckKey terminates program. */
    while( repeat )
    {
        /* On first loops, launch character threads. */
        _beginthread( Bounce, 0, (void *) (ch++)  );

        /* Wait one second between loops. */
        Sleep( 1000L );
    }
}

/* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */
void CheckKey( void *dummy )
{
    _getch();
    repeat = 0;    /* _endthread implied */

}

/* Bounce - Thread to create and and control a colored letter that moves
 * around on the screen.
 * Params: ch - the letter to be moved
 */
void Bounce( void *ch )
{
    /* Generate letter and color attribute from thread argument. */
    char    blankcell = 0x20;
    char    blockcell = (char) ch;
    BOOL    first = TRUE;
   COORD   oldcoord, newcoord;
   DWORD   result;


    /* Seed random number generator and get initial location. */
    srand( _threadid );
    newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
    newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );
    while( repeat )
    {
        /* Pause between loops. */
        Sleep( 100L );

        /* Blank out our old position on the screen, and draw new letter. */
        if( first )
            first = FALSE;
        else
         WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );
         WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord, &result );

        /* Increment the coordinate for next placement of the block. */
        oldcoord.X = newcoord.X;
        oldcoord.Y = newcoord.Y;
        newcoord.X += GetRandom( -1, 1 );
        newcoord.Y += GetRandom( -1, 1 );

        /* Correct placement (and beep) if about to go off the screen. */
        if( newcoord.X < 0 )
            newcoord.X = 1;
        else if( newcoord.X == csbi.dwSize.X )
            newcoord.X = csbi.dwSize.X - 2;
        else if( newcoord.Y < 0 )
            newcoord.Y = 1;
        else if( newcoord.Y == csbi.dwSize.Y )
            newcoord.Y = csbi.dwSize.Y - 2;

        /* If not at a screen border, continue, otherwise beep. */
        else
            continue;
        Beep( ((char) ch - 'A') * 100, 175 );
    }
    /* _endthread given to terminate */
    _endthread();
}

press any key to end

Exemplo de código a seguir demonstra como você pode usar o identificador de thread retornado por _beginthreadex com a API de sincronização WaitForSingleObject.O thread principal aguarda o segmento segundo terminar antes de continuar.Quando o segundo thread chama _endthreadex, ela faz com que seu objeto de segmento ir para o estado sinalizado. Isso permite que o thread principal para continuar a executar.Isso não pode ser concluído com _beginthread e _endthread, pois _endthread chamadas CloseHandle, destruir o objeto thread antes que pode ser definida como estado sinalizado.

// crt_begthrdex.cpp
// compile with: /MT
#include <windows.h>
#include <stdio.h>
#include <process.h>

unsigned Counter; 
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
    printf( "In second thread...\n" );

    while ( Counter < 1000000 )
        Counter++;

    _endthreadex( 0 );
    return 0;
} 

int main()
{ 
    HANDLE hThread;
    unsigned threadID;

    printf( "Creating second thread...\n" );

    // Create the second thread.
    hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );

    // Wait until second thread terminates. If you comment out the line
    // below, Counter will not be correct because the thread has not
    // terminated, and Counter most likely has not been incremented to
    // 1000000 yet.
    WaitForSingleObject( hThread, INFINITE );
    printf( "Counter should be 1000000; it is-> %d\n", Counter );
    // Destroy the thread object.
    CloseHandle( hThread );
}

Creating second thread... In second thread... Counter should be 1000000; it is-> 1000000

Equivalente do NET Framework

sistema::Threading::Thread::Start

Consulte também

Referência

Processo e ambiente de controle

_endthread, _endthreadex

anular

sair, _exit

GetExitCodeThread