_beginthread, _beginthreadex

스레드를 만듭니다.

중요중요

이 API는 Windows 런타임에서 실행 되는 응용 프로그램에서 사용할 수 없습니다.자세한 내용은 /zw에 지원 되는 CRT 함수.

uintptr_t _beginthread( // NATIVE CODE
   void( __cdecl *start_address )( void * ),
   unsigned stack_size,
   void *arglist 
);
uintptr_t _beginthread( // MANAGED CODE
   void( __clrcall *start_address )( void * ),
   unsigned stack_size,
   void *arglist 
);
uintptr_t _beginthreadex( // NATIVE CODE
   void *security,
   unsigned stack_size,
   unsigned ( __stdcall *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr 
);
uintptr_t _beginthreadex( // MANAGED CODE
   void *security,
   unsigned stack_size,
   unsigned ( __clrcall *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr 
);

매개 변수

  • start_address
    실행의 새 스레드를 시작 하는 루틴의 주소를 시작 합니다.에 대 한 _beginthread, 호출 규칙은 __cdecl (네이티브 코드)에 대 한 또는 __clrcall (예: 관리 되는 코드). 에 대 한 _beginthreadex, 되어 __stdcall (예: 네이티브 코드의 경우) 또는 __clrcall (관리 코드)에 대 한.

  • stack_size
    새 스레드 또는 0 스택 크기입니다.

  • Arglist
    새 스레드 또는 NULL에 전달할 인수 목록입니다.

  • Security
    에 대 한 포인터는 SECURITY_ATTRIBUTES 반환 된 핸들 자식 프로세스에 상속할 수 있는지 여부를 결정 하는 구조입니다.Null 인 경우, 핸들을 상속할 수 없습니다.NULL에 대 한 Windows 95 응용 프로그램 이어야 합니다.

  • Initflag
    초기 새 스레드의 상태 (0 실행 또는 CREATE_SUSPENDED 일시 중지에 대 한). 사용 하 여 ResumeThread 스레드 실행을 합니다.

  • Thrdaddr
    스레드 식별자를 수신 하는 32 비트 변수를 가리킵니다.수 NULL, 경우에 사용 되지 않습니다.

반환 값

성공 하면 각이 함수에 새로 만들어진된 스레드 핸들 반환. 하지만 너무 신속 하 게 새로 만든된 스레드를 종료 하는 경우 _beginthread 유효한 핸들을 반환할 수 있습니다 (의 내용은 Remarks 절)._beginthread오류를 경우에 L-1를 반환 errno 로 설정 된 EAGAIN 있을 경우 너무 많은 스레드를 EINVAL 인수가 잘못 되었거나 스택 크기가 올바르지 않습니다 경우 또는 EACCES 리소스가 부족 (예: 메모리)의 경우._beginthreadex경우에 오류 발생 시 0을 반환 errno 및 _doserrno 로 설정 됩니다.

경우 startaddress 는 NULL에 설명 된 대로 잘못 된 매개 변수 처리기를 호출 매개 변수 유효성 검사.실행을 계속 허용 되 면 이러한 함수를 설정 errno 에 EINVAL 및-1을 반환 합니다.

이러한 및 다른 반환 코드에 대 한 자세한 내용은 참조 하십시오 _sys_nerr, _doserrno, errno, _sys_errlist,.

에 대 한 자세한 내용은 uintptr_t을 참조 하십시오 표준 형식.

설명

_beginthread 함수에서 루틴의 실행을 시작 하는 스레드를 만드는 start_address.루틴에 start_address 사용 해야는 __cdecl (예: 네이티브 코드의 경우) 또는 __clrcall (관리 코드)에 대 한 호출 규칙 및 반환 값이 있어야 합니다.스레드 루틴에서 반환 될 때 자동으로 종료 됩니다.스레드에 대 한 자세한 내용은 다중 스레딩.

_beginthreadexWin32 유사한 CreateThread 자세한 API 보다 밀접 하 게 _beginthread 않습니다._beginthreadex다른 _beginthread 에 다음과 같은:

  • _beginthreadex세 개의 추가 매개 변수가 있습니다: initflag, security, 및 threadaddr.새 스레드는 지정 된 보안 (Windows NT)와 일시 중단 된 상태에서 만들 수 있으며 사용 하 여 액세스할 수 있습니다 thrdaddr, 스레드 식별자입니다.

  • 루틴에서 start_address 전달 _beginthreadex 사용 해야는 __stdcall (네이티브 코드)에 대 한 또는 __clrcall (관리 코드)에 대 한 호출 규칙 및 스레드의 종료 코드를 반환 해야 합니다.

  • _beginthreadexL-1 보다는 실패, 0을 반환합니다.

  • 스레드를 사용 하 여 만든 _beginthreadex 호출 하 여 종료 _endthreadex.

_beginthreadex 함수를 사용 하면 보다 스레드를 만드는 방법을 보다 자세하게 제어 _beginthread 않습니다._endthreadex 함수 보다 융통성 있는 이기도 합니다.예를 들어, _beginthreadex, 보안 정보를 사용, 초기 상태 (실행 중 또는 중지) 스레드 설정 및 새로 만든 스레드의 스레드 식별자를 가져옵니다.또한 반환 되는 스레드 핸들을 사용할 수 있습니다 _beginthreadex 동기화 Api와 없는 _beginthread.

안전 하 게 사용 하는 _beginthreadex 보다 _beginthread.스레드를 생성 하는 경우 _beginthread 핸들이 호출자에 게 반환을 신속 하 게 종료 _beginthread 잘못 되거나, 악화 될, 다른 스레드를 가리킨 수도 있습니다.그러나 핸들을 반환 하 _beginthreadex 의 호출자에 의해 닫을 수 있습니다 _beginthreadex, 올바른 핸들이 경우에 보장 됩니다 _beginthreadex 오류를 반환 합니다.

호출할 수 있는 _endthread 또는 _endthreadex 명시적으로; 스레드를 종료 하도록 그러나 _endthread 또는 _endthreadex 스레드가 매개 변수로 전달 하는 루틴에서 반환 될 때 자동으로 호출 됩니다.호출 하 여 스레드를 종료 endthread 또는 _endthreadex 스레드에 대해 할당 된 자원의 적절 한 복구를 보장 하는 데 도움이 됩니다.

_endthread자동으로 스레드 핸들을 닫습니다 (반면 _endthreadex 하지 않습니다).따라서 사용 하는 경우 _beginthread 및 _endthread를 명시적으로 스레드 핸들은 Win32 호출 하 여 닫지 마십시오 CloseHandle API입니다.이 동작은 win32에서 다릅니다 ExitThread API입니다.

[!참고]

Libcmt.lib로 연결 하는 실행 파일을 Win32 호출 하지 마십시오 ExitThread API입니다. 이 런타임 시스템 할당 된 리소스를 회수 하지 못하게 합니다._endthread및 _endthreadex 할당 된 스레드가 리소스를 회수 하 고 호출 ExitThread.

운영 체제에서 스택 할당 처리 하면 어느 _beginthread 또는 _beginthreadex 이라고 합니다. 이러한 함수 중 하나에 스레드 스택 주소를 전달할 필요가 없습니다.또한는 stack_size 인수는 0에서 운영 체제의 경우 같은 값을 사용로 지정 된 스택 주 스레드에 대 한 될 수 있습니다.

arglist새로 만들어진된 스레드에 전달 되는 매개 변수가입니다.일반적으로 문자열에 같은 데이터 항목의 주소입니다.arglist수 NULL 필요 하지 않으면 있지만 _beginthread 및 _beginthreadex 새 스레드로 전달 하는 값을 제공 해야 합니다.스레드에서 하는 경우 모든 스레드가 종료 된 abort, exit, _exit, 또는 ExitProcess.

해당 부모 스레드에서 새 스레드 로캘을 상속 합니다.호출 하 여 당 스레드 로캘을 사용 하면 _configthreadlocale (전역적으로 또는 새 스레드에 대 한만), 스레드의 해당 로캘 독립적으로 부모 로부터 호출 하 여 변경할 수 있습니다 setlocale 또는 _wsetlocale.자세한 내용은 로케일.

혼합형 및 순수형 코드에 대 한 _beginthread 및 _beginthreadex 모두 네이티브 호출 규칙 함수 포인터를 다른 기록을 차지 하나 두 오버 로드를 포함 한 __clrcall 함수 포인터입니다.응용 프로그램 도메인 안전 하며 절대로 첫 번째 오버 로드 수 없습니다 수 있습니다.혼합 또는 순수 코드를 작성 하는 경우에 관리 되는 리소스에 액세스 하기 전에 새 스레드를 올바른 응용 프로그램 도메인을 입력 하는 확인 해야 합니다.예를 들어,를 사용 하 여 이렇게 수 있습니다 call_in_appdomain 함수.두 번째 오버 로드는 안전한 도메인 응용 프로그램입니다. 새로 만들어진된 스레드는 호출자의 응용 프로그램 도메인에서 항상 이루어지는 _beginthread 또는 _beginthreadex.

요구 사항

루틴

필수 헤더

_beginthread

<process.h>

_beginthreadex

<process.h>

자세한 호환성에 대 한 내용은 호환성 소개에서 합니다.

라이브러리

다중 스레드 버전의 C 런타임 라이브러리 만.

사용 _beginthread 또는 _beginthreadex, 응용 프로그램에서 다중 스레드 C 런타임 라이브러리 중 하나에 연결 해야 합니다.

예제

다음 예제에서는 _beginthread 및 _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();
}
  종료 하려면 아무 키나를 누르십시오.

다음 샘플 코드에서 반환 되는 스레드 핸들을 사용 하는 방법을 보여 줍니다. _beginthreadex 동기화 API WaitForSingleObject.계속 하기 전에 끝내려면 두 번째 스레드에 대 한 주 스레드를 기다립니다.두 번째 스레드를 호출할 때 _endthreadex, 스레드 개체를 신호 된 상태로 이동 하면 됩니다.이 기본 스레드를 계속 실행할 수 있습니다.함께 수행할 수 없습니다. _beginthread 및 _endthread때문에 _endthread 호출 CloseHandle, thread 개체 파괴 하는 신호를 받은 상태로 설정할 수 있습니다.

// 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 );
}
  
  
  

해당 .NET Framework 항목

System::Threading::Thread::Start

참고 항목

참조

프로세스 및 환경 제어

_endthread, _endthreadex

abort

exit, _exit

GetExitCodeThread