Aracılığıyla paylaş


_beginthread, _beginthreadex

Bir iş parçacığı oluşturur.

Önemli notÖnemli

Bu API yürütün uygulamalarda kullanılamaz Windows Çalışma Zamanı veya kullanarak derlenmiş clr:pure geç.Daha fazla bilgi için /ZW ile desteklenmiyor CRT işlevleri.

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

Parametreler

  • start_address
    Başlangıç adresi bir yordamının yeni bir iş parçacığı yürütülmesine başlar.İçin _beginthread, çağırma kuralı bozulmuş __cdecl (için yerel kod) veya __clrcall (için yönetilen kod); için _beginthreadex, ya da __stdcall (için yerel kod) veya __clrcall (için yönetilen kod).

  • stack_size
    Toplu iş boyutu için yeni bir iş parçacığı veya 0.

  • arglist
    Yeni bir iş parçacığı veya NULL iletilecek bağımsız değişken listesi.

  • Security
    İşaretçi bir SECURITY_ATTRIBUTES yapısı alt işlemler tarafından döndürülen tanıtıcı devralınan olup olmadığını belirler.Varsa Security null, tanıtıcı devralınan.NULL for Windows 95 uygulamaları olması gerekir.

  • initflag
    Yeni bir iş parçacığı ilk durumunu denetlemek bayraklar.Ayarlama initflag için 0 hemen çalıştırmak için veya CREATE_SUSPENDED askıya alınmış bir durumda; dizi oluşturmak için kullanmak ResumeThread'i iş parçacığı yürütmek için.Ayarlama initflag için STACK_SIZE_PARAM_IS_A_RESERVATION kullanılacak bayrağı stack_size bayt; Yığındaki ilk yedeği boyutu olarak Bu bayrak belirtilmezse, stack_size yürütme boyutunu belirtir.

  • thrdaddr
    İş parçacığı tanımlayıcısını alan 32-bit değişken işaret ediyor.NULL ise, kullanılmaz.

Dönüş Değeri

Başarılı olursa, bu işlevlerin her bir tanıtıcı için yeni oluşturulan dizi döndürür; Ancak, yeni oluşturulan iş parçacığı çok hızlı bir şekilde çıkılıyorsa _beginthread geçerli bir tanıtıcı döndürebilir değil.(Açıklamalar bölümünde konuya bakın.) Bir hata _beginthread -1 M döndürür ve errno ayarlamak EAGAIN varsa çok fazla iş parçacığı, çok EINVAL bağımsız değişkeni geçersiz ya da toplu iş boyutu yanlış ise veya için EACCES kaynaklar (örneğin bellek) yetersiz olduğunda.Bir hata _beginthreadex 0 döndürür ve errno ve _doserrno ayarlanır.

Varsa startaddress null, açıklandığı gibi geçersiz parametre işleyici çağrılır Parametre Doğrulama.Devam etmek için yürütme izin verilirse, bu işlevler kümesi errno için EINVAL ve -1 döndürür.

Bu ve diğer dönüş kodları hakkında daha fazla bilgi için bkz: errno, _doserrno, _sys_errlist, and _sys_nerr.

uintptr_t hakkında daha fazla bilgi için bkz. Standart Türler.

Notlar

_beginthread Bir işlev oluşturur bir yordam yürütülmesine başlar bir iş parçacığı start_address.Yordam konumunda start_address kullanmalıdır __cdecl (için yerel kod) veya __clrcall (için yönetilen kod) çağırma ve bir dönüş değerine sahip olmalıdır.Dizi bu yordamı döndürüldüğünde, otomatik olarak sonlandırılır.İş parçacığı hakkında daha fazla bilgi için bkz Eski Kod için Çoklu İş Parçacığı Kullanma Desteği (Visual C++).

_beginthreadexWin32 benzer CreateThread API daha fazla daha yakın _beginthread yok._beginthreadexfarklı _beginthread aşağıdaki yollarla:

  • _beginthreadexüç ek parametrelere sahip: initflag, security, ve threadaddr.Yeni bir dizi durumunda, belirtilen bir güvenlik ile oluşturulabilir ve kullanılarak erişilebilir thrdaddr, iş parçacığı tanımlayıcısını olduğu.

  • Yordam konumunda start_address için geçirilen _beginthreadex kullanmalıdır __stdcall (için yerel kod) veya __clrcall (için yönetilen kod) çağırma ve bir iş parçacığı çıkış kodu döndürmesi gerekir.

  • _beginthreadex0-1 M yerine hatası döndürür.

  • Kullanılarak oluşturulan bir iş parçacığı _beginthreadex bir çağrı tarafından sonlandırılır _endthreadex.

_beginthreadex İşlevi size daha diziyi nasıl oluşturulduğu üzerinde daha fazla denetim _beginthread yok._endthreadex İşlevi daha esnek de.Örneğin, ile _beginthreadex, güvenlik bilgileri kullanın, ilk durumu (çalışan veya askıya) iş parçacığı ayarlayın ve yeni oluşturulan iş parçacığı iş parçacığı tanımlayıcısını alır.Tarafından döndürülen dizi tanıtıcı de kullanabilirsiniz _beginthreadex ile yapamayacağınız API'leri, eşitleme ile _beginthread.

Kullanılacak güvenlidir _beginthreadex daha _beginthread.Varsa tarafından üretilen iş parçacığı _beginthread hızlı bir şekilde, arayanı, döndürülen tanıtıcı çıkar _beginthread geçersiz veya başka bir diziye noktası.Ancak, tarafından döndürülen tanıtıcı _beginthreadex arayan tarafından kapatılması gerekir _beginthreadex, bu geçerli bir tanıtıcı olması garanti _beginthreadex bir hata döndürmedi.

Çağırabilirsiniz _endthread veya _endthreadex açıkça bir iş parçacığı; sonlandırmak için Ancak, _endthread veya _endthreadex iş parçacığı parametre olarak geçirilen yordamını döndürüldüğünde otomatik olarak çağrılır.Bir iş parçacığı çağrısıyla sonlandırma _endthread veya _endthreadex iş parçacığı için ayrılan kaynakları doğru kurtarma sağlamaya yardımcı olur.

_endthreadiş parçacığı tutamacı ise otomatik olarak kapanır _endthreadex yoktur.Bu nedenle, kullandığınızda _beginthread ve _endthread, açıkça iş parçacığı tutamacı Win32 çağırarak kapatmayın CloseHandle API.Bu davranış Win32 farklıdır ExitThread API.

[!NOT]

Libcmt.lib ile bağlantılı bir yürütülebilir dosya için Win32 çağırmayın ExitThread API, çalışma zamanı sistem reclaiming öğesinden engellemez, böylece ayrılan kaynakları._endthreadve _endthreadex ayrılan iş parçacığı kaynakları geri kazanmak ve çağırma ExitThread.

İşletim sistemi yığının ayırma işler olduğunda ya da _beginthread veya _beginthreadex çağrılır; iş parçacığı yığın adresini ya da bu işlevlerin geçirmek zorunda değilsiniz.Ayrıca, stack_size bağımsız değişkeni, işletim sistemi durumu kullanma aynı değeri belirtilen yığın ana iş parçacığı için 0, olabilir.

arglistYeni oluşturulan diziye iletilecek bir parametredir.Genel olarak, bu bir karakter dizesi gibi bir veri öğesi adresidir.arglistgerekmiyorsa, boş olabilir ancak _beginthread ve _beginthreadex için yeni bir dizi iletmek için bazı değer verilmesi gerekir.Tüm çağrıları iş parçacığı, tüm diziler sonlandırılır abort, exit, _exit, veya ExitProcess.

Yeni bir dizi yerel kendi üst parçacığından devralınır.İş parçacığı başına yerel bir çağrı tarafından etkinleştirilip etkinleştirilmediğini _configthreadlocale (genel veya yeni dizileri için yalnızca), iş parçacığı, yerel ayar bağımsız olarak üst öğesinden çağırarak değiştirebilirsiniz setlocale veya _wsetlocale.Daha fazla bilgi için bkz. Yerel Ayar.

Karışık ve saf kodu için _beginthread ve _beginthreadex her iki aşırı yüklemelerine sahiptir — bir yerel çağırma kuralı işlev işaretçisi, diğer alır alır bir __clrcall işlev işaretçisi.İlk aşırı yüklemesini uygulama etki alanı güvenli ve hiçbir zaman değil olabilir.Karma veya saf kod yazıyorsanız, yönetilen kaynakları erişen önce yeni bir dizi doğru uygulama etki alanı girer emin olmalısınız.Örneğin, kullanarak bunu call_in_appdomain İşlevi.İkinci aşırı yüklemesi, uygulama etki alanı güvenli, Yeni oluşturulan iş parçacığı her zaman arayanı, uygulama etki alanı ulaşır _beginthread veya _beginthreadex.

Gereksinimler

Yordam

Gerekli başlık

_beginthread

< process.h >

_beginthreadex

< process.h >

Uyumluluk hakkında daha fazla bilgi için bkz. Uyumluluk.

Kitaplıklar

Çok iş parçacıklı sürümleri C çalışma zamanı kitaplıkları yalnızca.

Kullanılacak _beginthread veya _beginthreadex, uygulama çok iş parçacıklı C çalışma zamanı kitaplıkları biri ile bağlamanız gerekir.

Örnek

Aşağıdaki örnek, kullanır _beginthread ve _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 * );
void CheckKey( void * );

// GetRandom returns a random integer between min and max.
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
// GetGlyph returns a printable ASCII character value
#define GetGlyph( val ) ((char)((val + 32) % 93 + 33))

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

int main()
{
    int param = 0;
    int * pparam = &param;

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

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

    // Loop until CheckKey terminates program or 1000 threads created. 
    while( repeat && param < 1000 )
    {
        // launch another character thread.
        _beginthread( Bounce, 0, (void *) pparam );

        // increment the thread parameter
        param++;

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

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

// Bounce - Thread to create and and control a colored letter that moves
// around on the screen.
//
// Params: parg - the value to create the character from
void Bounce( void * parg )
{
    char       blankcell = 0x20;
    CHAR_INFO  ci;
    COORD      oldcoord, cellsize, origin;
    DWORD      result;
    SMALL_RECT region;

    cellsize.X = cellsize.Y = 1;
    origin.X = origin.Y = 0;

    // Generate location, letter and color attribute from thread argument.
    srand( _threadid );
    oldcoord.X = region.Left = region.Right = 
        GetRandom(csbi.srWindow.Left, csbi.srWindow.Right - 1);
    oldcoord.Y = region.Top = region.Bottom = 
        GetRandom(csbi.srWindow.Top, csbi.srWindow.Bottom - 1);
    ci.Char.AsciiChar = GetGlyph(*((int *)parg));
    ci.Attributes = GetRandom(1, 15);

    while (repeat)
    {
        // Pause between loops.
        Sleep( 100L );

        // Blank out our old position on the screen, and draw new letter.
        WriteConsoleOutputCharacterA(hStdOut, &blankcell, 1, oldcoord, &result);
        WriteConsoleOutputA(hStdOut, &ci, cellsize, origin, &region);

        // Increment the coordinate for next placement of the block.
        oldcoord.X = region.Left;
        oldcoord.Y = region.Top;
        region.Left = region.Right += GetRandom(-1, 1);
        region.Top = region.Bottom += GetRandom(-1, 1);

        // Correct placement (and beep) if about to go off the screen.
        if (region.Left < csbi.srWindow.Left)
            region.Left = region.Right = csbi.srWindow.Left + 1;
        else if (region.Right >= csbi.srWindow.Right)
            region.Left = region.Right = csbi.srWindow.Right - 2;
        else if (region.Top < csbi.srWindow.Top)
            region.Top = region.Bottom = csbi.srWindow.Top + 1;
        else if (region.Bottom >= csbi.srWindow.Bottom)
            region.Top = region.Bottom = csbi.srWindow.Bottom - 2;

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

Örnek uygulamayı sonlandırmak için herhangi bir tuşa basın.

Aşağıdaki örnek kod tarafından döndürülen dizi tanıtıcı nasıl kullanacağınızı göstermektedir _beginthreadex eşitleme API ile WaitForSingleObject.Devam etmeden önce sonlandırmak ikinci bir iş parçacığı için ana iş parçacığı bekler.İkinci bir iş parçacığı olduğunda çağırır _endthreadex, sinyal verilmiş durumuna gitmek kendi iş parçacığı nesnesi neden olur.Bu, birincil iş parçacığı çalışmaya devam etmesini sağlar.Bu ile yapılamaz _beginthread ve _endthread, çünkü _endthread çağrıları CloseHandle, sinyal verilmiş durumuna ayarlamadan önce iş parçacığı nesneyi siler.

// 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 Eşdeğeri

System::Threading::thread::Start

Ayrıca bkz.

Başvuru

Süreç ve Ortam Denetimi

_endthread, _endthreadex

durdur

çıkış, _exit

GetExitCodeThread