Tricks of the Windows Game Programming Gurus:Algorithms, Data Structures, Memory Management, and Multithreading

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

Basically, `CloseHandle()` invalidates the specified object handle, decrements the object’s handle count, and performs object retention checks. Once the last handle to an object is closed, the object is removed from the operating system.

> Warning: The new thread handle is created with full access to the new thread. If a security descriptor is not provided, the handle can be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.

Now let’s take a look at some code that could represent a thread you would pass for processing to `CreateThread()`:

    DWORD WINAPI My_Thread(LPVOID data)

    {

    // .. do work

    // return an exit code at end, whatever is appropriate for your app

    return(26);

    } // end My_Thread

Now you have everything you need to create your first multithreaded app. The first example will illustrate the creation of a single thread, along with the primary thread of execution (the main program). The secondary thread will print out the number 2, and the primary thread will print out the number 1. `DEMO11_5.CPP` contains the complete program and is shown here for reference:

    // DEMO11_5.CPP - Creates a single thread that prints

    // simultaneously while the Primary thread prints.

    // INCLUDES ////////////////////////////////////////////////

    #define WIN32_LEAN_AND_MEAN  // make sure win headers

                                 // are included correctly

    #include <windows.h>    // include the standard windows stuff

    #include <windowsx.h>   // include the 32 bit stuff

    #include <conio.h>

    #include <stdlib.h>

    #include <stdarg.h>

    #include <stdio.h>

    #include <math.h>

    #include <io.h>

    #include <fcntl.h>

    // DEFINES ////////////////////////////////////////////////

    // PROTOTYPES //////////////////////////////////////////////

    DWORD WINAPI Printer_Thread(LPVOID data);

    // GLOBALS /////////////////////////////////////////////////

    // FUNCTIONS ///////////////////////////////////////////////

    DWORD WINAPI Printer_Thread(LPVOID data)

    {

    // this thread function simply prints out data

    // 25 times with a slight delay

    for (int index=0; index<25; index++)

        {

        printf("%d ",data); // output a single character

        Sleep(100);         // sleep a little to slow things down

        } // end for index

    // just return the data sent to the thread function

    return((DWORD)data);

    } // end Printer_Thread

    // MAIN ///////////////////////////////////////////////////////////////

    void main(void)

    {

    HANDLE thread_handle;  // this is the handle to the thread

    DWORD  thread_id;      // this is the id of the thread

    // start with a blank line

    printf("\nStarting threads…\n");

    // create the thread, IRL we would check for errors

    thread_handle = CreateThread(NULL,        // default security

                     0,                // default stack

                     Printer_Thread,  // use this thread function

                     (LPVOID)1,       // user data sent to thread

                     0,                // creation flags, 0=start now.

                     &thread_id);    // send id back in this var

    // now enter into printing loop, make sure this takes longer than thread,

    // so thread finishes first

    for (int index=0; index<50; index++)

        {

        printf("2 ");

        Sleep(100);

        } // end for index

    // at this point the thread should be dead

    CloseHandle(thread_handle);

    // end with a blank line

    printf("\nAll threads terminated.\n");

    } // end main

Sample output:

    Starting threads…

    2 1 2 1 2 1 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2

    2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 2

    2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

    All threads terminated.

As you can see from the sample output, each thread of execution runs for a short time, and then the OS switches context to the next waiting thread. In this case, the OS simply toggles back and forth between the primary thread and the secondary thread.

Now let’s try to create multiple threads. You can make a slight modification to `DEMO11_5.CPP` to add this functionality. All you need to do is call the `CreateThread()` function multiple times, once for each thread. Also, the data sent to the thread will be the value to print out each time so you can differentiate each thread from one another.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.