Boost logo

Boost :

From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2001-08-21 14:37:47


> Hmm... I was not aware that POSIX operated this way. Seems to me
> that this means the pthreads-win32 isn't compliant (unless they
> found some way to work around this).
> The main thread on Win32 is synonymous with the process...
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/hh/winbase/prothred_531g.asp

"Remarks

 ExitThread is the preferred method of exiting a thread.
 When this function is called (either explicitly or by
 returning from a thread procedure), the current thread's
 stack is deallocated and the thread terminates. The
 entry-point function of all attached dynamic-link
 libraries (DLLs) is invoked with a value indicating
 that the thread is detaching from the DLL.

 If the thread is the last thread in the process when this
 function is called, the thread's process is also terminated."

also, see _endthread(ex) and e.g. the following slightly modified
(to illustrate process "auto-"termination on last thread termination)
MSDN sample available at

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_crt__endthread.2c_.

endthreadex.asp

regards,
alexander.

/* BEGTHRD.C illustrates multiple threads using functions:
 *
 * _beginthread _endthread
 *
 *
 * 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, select the
 * Multi-Threaded runtime library in the compiler Project Options 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 */
CONSOLE_SCREEN_BUFFER_INFO csbi; /* Console information structure */

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

    do {
      _beginthread( Bounce, 0, (void *)ch );
      _beginthread( Bounce, 0, (void *)ch );
      _beginthread( Bounce, 0, (void *)ch );
    } while ( 'Z' > ch++ );
    printf( "\nterminating main thread... enter char to end process!" );
    _endthread();
    // should never reach this point
    printf( "\noops!!" );
}

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk