Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Watcom C Library Reference - <u>synopsis:</u> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Synopsis:
    #include <process.h>
    #if defined(__386__)
    #   define FAR
    #else
    #   define FAR __far
    #endif

    #if defined(__NT__)
    unsigned long _beginthread(
            void (*start_address)(void *),
            unsigned stack_size,
            void     *arglist);
    unsigned long _beginthreadex(
            void *security,
            unsigned stack_size,
            unsigned (__stdcall *start_address)(void *),
            void *arglist,
            unsigned initflag,
            unsigned *thrdid );
    #else
    int FAR _beginthread(
            void (FAR *start_address)(void FAR *),
            void FAR *stack_bottom,
            unsigned stack_size,
            void FAR *arglist );
    #endif

Description:
    The _beginthread function is used to start a new thread of execution at
    the function identified by start_address with a single parameter
    identified by arglist.

    For each operating environment under which _beginthread is supported,
    the _beginthread function uses the appropriate system call to begin a
    new thread of execution.

    The new thread will use the memory identified by stack_bottom and
    stack_size for its stack.

    Note for 16-bit applications:  If the stack is not in DGROUP (i.e., the
    stack pointer does not point to an area in DGROUP) then you must compile
    your application with the "zu" option.  For example, the pointer
    returned by  malloc in a large data model may not be in DGROUP.  The
    "zu" option relaxes the restriction that the SS register contains the
    base address of the default data segment, "DGROUP".  Normally, all data
    items are placed into the group DGROUP and the SS register contains the
    base address of this group.  In a thread, the SS register will likely
    not contain the base address of this group.  When the "zu" option is
    selected, the SS register is volatile (assumed to point to another
    segment) and any global data references require loading a segment
    register such as DS with the base address of DGROUP.

    Note for OS/2 32-bit applications:  Memory for a stack need not be
    provided by the application.  The stack_bottom may be NULL in which case
    the run-time system will provide a stack.  You must specify a non-zero
    stack_size for this stack.

    Note for Win32 applications:  Memory for a stack is provided by the
    run-time system.  The size of the stack is determined by stack_size and
    must not be zero.

    The  _beginthreadex function can be used to create a new thread, in a
    running or suspended state specified by initflag, with security
    attributes specified by security.

    The initial state of the new thread (running or suspended) is specified
    by the initflag argument.  If the  CREATE_SUSPENDED flag (WINBASE.H) is
    specified, the thread is created in a suspended state, and will not run
    until the Win32  ResumeThread function is called with the thread handle
    as an argument.  If this value is zero, the thread runs immediately
    after creation.

    The security descriptor for the new thread is specified by the security
    argument.  This is a pointer to a Win32  SECURITY_ATTRIBUTES structure
    (see Microsoft's Win32 Programmer's Reference for more information).
     For default behaviour, the security structure pointer can be  NULL.

    The thread identifier is returned in the location identified by the
    thrdid argument.

    The thread ends when it exits from its main function or calls  exit,
     _exit,  _endthread or  _endthreadex.

    The variable/function  _threadid which is defined in <stddef.h> may be
    used by the executing thread to obtain its thread ID.  In the 16-bit
    libraries,  __threadid is a far pointer to an int.  In the 32-bit
    libraries, it is a function that returns an int.

    There is no limit to the number of threads an application can create
    under Windows NT and Windows 95.

    There is a limit to the number of threads an application can create
    under 16-bit OS/2 and 32-bit NetWare.  The default limit is 32.  This
    limit can be adjusted by statically initializing the unsigned global
    variable __MaxThreads.

    Under 32-bit OS/2, there is no limit to the number of threads an
    application can create.  However, due to the way in which multiple
    threads are supported in the Watcom libraries, there is a small
    performance penalty once the number of threads exceeds the default limit
    of 32 (this number includes the initial thread).  If you are creating
    more than 32 threads and wish to avoid this performance penalty, you can
    redefine the threshold value of 32.  You can statically initialize the
    global variable __MaxThreads.

    By adding the following line to your multi-threaded application, the new
    threshold value will be set to 48.


         unsigned __MaxThreads = { 48 };


Returns:
    Under Win32, the _beginthread function returns the thread handle for the
    new thread if successful; otherwise it returns 0 to indicate that the
    thread could not be started.

    Under all other systems that support the _beginthread function (OS/2,
    Netware and QNX), it returns the thread ID for the new thread if
    successful; otherwise it returns -1 to indicate that the thread could
    not be started.

    The  _beginthreadex function returns the thread handle for the new
    thread if successful; otherwise it returns 0 to indicate that the thread
    could not be started.

    When the thread could not be started, the value of  errno could be set
    to  EAGAIN if there are too many threads, or to  EINVAL if the argument
    is invalid or the stack size is incorrect, or to  ENOMEM if there is not
    enough available memory.

Example:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <malloc.h>
    #include <process.h>
    #include <dos.h>

    #if defined(__386__)
      #define FAR
      #define STACK_SIZE    8192
    #else
      #define FAR           __far
      #define STACK_SIZE    4096
    #endif

    static volatile int     WaitForThread;

    void FAR child( void FAR *parm )
      {
        char * FAR *argv = (char * FAR *) parm;
        int  i;

        printf( "Child thread ID = %x\n", *_threadid );
        for( i = 0; argv[i]; i++ ) {
          printf( "argv[%d] = %s\n", i, argv[i] );
        }
        WaitForThread = 0;
        _endthread();
      }

    void main()
      {
        char           *args[3];
    #if defined(__NT__)
        unsigned long   tid;
    #else
        char           *stack;
        int             tid;
    #endif

        args[0] = "child";
        args[1] = "parm";
        args[2] = NULL;
        WaitForThread = 1;
    #if defined(__NT__)
        tid = _beginthread( child, STACK_SIZE, args );
        printf( "Thread handle = %lx\n", tid );
    #else
      #if defined(__386__)
        stack = (char *) malloc( STACK_SIZE );
      #else
        stack = (char *) _nmalloc( STACK_SIZE );
      #endif
        tid = _beginthread( child, stack, STACK_SIZE, args );
        printf( "Thread ID = %x\n", tid );
    #endif
        while( WaitForThread ) {
            sleep( 0 );
        }
      }

Classification:
    WATCOM

Systems:
     _beginthread - Win32, QNX/32, OS/2 1.x(MT), OS/2 1.x(DL), OS/2-32,
    Netware

    _beginthreadex - Win32

See Also:
    _endthread

See Also: _endthread

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson