beginthread,beginthreadex
建立一个线程。
unsigned long beginthread(void(cdecl *startaddress)(void*),unsigned stacksize, void *arglist);
unsigne dlong beginthreadex(void *security,unsignedstacksize,unsigned(stdcall *startaddress) (void *), void *arglist,unsignedinitflag,unsigned *thrdaddr);
例程 需要的头文件 兼容性
beginthread <process.h> Win NT,Win 95
beginthreadex <process.h> Win NT,Win 95
对于另外兼容性的信息,参见引言中的兼容性
库
LIBC.LIB 单线程静态库,零售版本
LIBCMT.LIB 多线程静态库,零售版本
MSVCRT.LIB MSVCRT.DLL的输入库,零售版本
为了使用beginthread或beginthreadex,该应用必须与多线程C运行库之一进行链接。
返回值
如果成功,这些函数返回最近建立的线程的句柄,出现一个错误时,beginthread返回-1在这种情况下如果有太多的线程,则errno设置为EAGAIN,如果参量无效或栈尺寸不正确,则errno设置为EINVAL。在出现一个错误时,beginthreadex返回0,这种情况下errno和doserrno都被设置。
参数
startaddress
开始执行新线程的例程的起始地址。
Stacksize
新线程的栈尺寸或0。
Arglist
传递给新线程的参量表或NULL。
Security
新线程的安全指示符;对于Windows 95应用必须为NULL。
Initflag
新线程的初始状态(运行时返回0或暂停时返回CREATESUSPEND)。
Thrdaddr
新函数的地址。
说明
beginthread函数建立一个线程,开始startaddress处例程的执行。在startaddress处的例程必须使用cdecl调用约定且没有返回值,当该线程从这个例程返回时,它自动终止。
.beginthredex比beginthread更紧密地汇编Win32 Create ThreadAPI函数,beginthreadex在如下方面不同于beginthread:
.eginthreadex有另外三个参数:initflag、security和threadaddr。新线程可以在暂停状态中建立,使用指定的安全方式(仅在Windows NT下),可以使用thrdadar访问,它是线程标识符。
.tartaddress处的程序传送给beginthreadex,必须使用stdcall调用约定且必须返回一个线程退出码。
失败时beginthreadex返回0,而不是-1。
.eginthreadex建立的线程通过调用endthreadex终止。
你可以显式调用endthread或endthreadex终止一个线程,但当该线程从作为参量传递的例程返回时自动调用endthread或endthreadex。通过调用endthread或endthreadex终止一个线程帮助确保恢复该线程分配的资源。
endthread自动关闭该线程句柄(而endthreadex不这样),因此,当使用beginthread和endthread时,通过调用Win32 CloseHandle API函数并不显式关闭该线程句柄。这个行为不同于Win32 ExitThread API函数。
注意:对于与LIBCMT.LIB链接的可执行文件,不要调用Win32ExitThread API函数;这防止该运行系统要求收回分配的资源。endthread和endthreadex要求收回分配的线程资源,然后调用ExitThread。在beginthread或beginthreadex被调用时,操作系统处理栈的分配你不需要传送线程栈地址给这些函数。另外,stacksize参量可以为0,在这种情况下操作系统使用与主线程中指定的栈相同的值。
arglist是传送给最近建立的线程的参数。它通常是一个数据项例如字符串的地址。
arglist如果不需要可以为NULL,但beginthread和beginthreadex必须提供一些传递给新线程的值。如果任何线程调用abort、exit、exit或ExitProcess,则所用线程被终止。
例子
/* BEGTHRD.C illustrates multiple threads using functions:
*
* beginthreadendthread
*
*
* This program requires the multithreaded library. For example,
* compile with the following command line:
*CL /MT /D "X86" BEGTHRD.C
*
* If you are using the Visual C++ development environment, selectthe
* Multi-Threaded runtime library in the compiler Project Settings
* dialog box.
*
*/
#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 */ CONSOLESCREENBUFFERINFO csbi; /* Console informationstructure */
void main()
{
CHAR ch = 'A';
hStdOut = GetStdHandle( STDOUTPUTHANDLE );
/* 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 thatmoves
* around on the screen.
*
* Params: ch - the letter to be moved
*/
void Bounce( void *ch )
{
/* Generate letter and color attribute from thread argument. */
charblankcell = 0x20;
charblockcell = (char) ch;
BOOLfirst = 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, &blankcell, 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();
}
参见
endthread,abort,exit