C++
  Home arrow C++ arrow Page 7 - Multithreading in C++
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

Multithreading in C++
By: McGraw-Hill/Osborne
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 171
    2005-07-14

    Table of Contents:
  • Multithreading in C++
  • An Overview of the Windows Thread Functions
  • Priority Classes
  • The Windows Synchronization Objects
  • The Thread Control Panel
  • A Closer Look at the Thread Control Panel
  • Demonstrating the Control Panel
  • A Multithreaded Garbage Collector
  • Synchronizing Access to gclist
  • The Entire Multithreaded Garbage Collector
  • Using the Multithreaded Garbage Collector

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Multithreading in C++ - Demonstrating the Control Panel


    (Page 7 of 11 )

    Here is a program that includes the thread control panel and demonstrates its use. Sample output is shown in Figure 3-2. The program creates a main window and defines two child threads. When started, these threads simply count from 0 to 50,000, displaying the count in the main window. These threads can be controlled by activating a thread control panel.

    To use the program, first begin execution of the threads by selecting Start Threads from the Threads menu (or by pressing F2) and then activate the thread control panels by selecting Control Panels from the Threads menu (or by pressing F3). Once the control panels are active, you can experiment with different priority settings and so on.


    Figure 3-2.  Sample output from the thread control panel sample program

    NOTE


    It is beyond the scope of this book to teach Windows programming. However, the operation of this sample program is straightforward and should be easily understood by all Windows programmers.

    // Demonstrate the thread control panel.
    #include <windows.h>
    #include <process.h>
    #include "thrdapp.h"
    #include "tcp.cpp"
    const int MAX = 500000;
    LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
    unsigned __stdcall MyThread1(void * param);
    unsigned __stdcall MyThread2(void * param);
    char str[255]; // holds output strings
    unsigned tid1, tid2; // thread IDs
    HANDLE hThread1, hThread2; // thread handles
    HINSTANCE hInst; // instance handle
    int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
                       LPSTR args, int winMode)
    {
      HWND hwnd;
      MSG msg;
      WNDCLASSEX wcl;
      HACCEL hAccel;
      // Define a window class.
      wcl.cbSize = sizeof(WNDCLASSEX);
      wcl.hInstance = hThisInst;     // handle to this instance
      wcl.lpszClassName = "MyWin";   // window class name
      wcl.lpfnWndProc = WindowFunc;  // window function
      wcl.style = 0;                 // default style
      wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon
      wcl.hIconSm = NULL; // use small version of large icon
      wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style
      wcl.lpszMenuName = "ThreadAppMenu"; // main menu
      wcl.cbClsExtra = 0; // no extra memory needed
      wcl.cbWndExtra = 0;
      // Make the window background white.
      wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
      // Register the window class.
      if(!RegisterClassEx(&wcl)) return 0;
      /* Now that a window class has been registered, a window
         can be created. */
      hwnd = CreateWindow(
        wcl.lpszClassName, // name of window class
        "Using a Thread Control Panel", // title
        WS_OVERLAPPEDWINDOW, // window style - normal
        CW_USEDEFAULT, // X coordinate - let Windows decide
        CW_USEDEFAULT, // Y coordinate - let Windows decide
        260,           // width
        200,           // height
        NULL,          // no parent window
        NULL,          // no override of class menu
        hThisInst,     // instance handle
        NULL           // no additional arguments
      );
      hInst = hThisInst; // save instance handle
      // Load the keyboard accelerators.
      hAccel = LoadAccelerators(hThisInst, "ThreadAppMenu");
      // Display the window.
      ShowWindow(hwnd, winMode);
      UpdateWindow(hwnd);
      // Create the message loop.
      while(GetMessage(&msg, NULL, 0, 0))
      {
        if(!TranslateAccelerator(hwnd, hAccel, &msg)) {  
          TranslateMessage(&msg); // translate keyboard messages
          DispatchMessage(&msg); // return control to Windows
        }
      }
      return msg.wParam;
    }
    /* This function is called by Windows and is passed
       messages from the message queue.
    */
    LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
                                WPARAM wParam, LPARAM lParam)
    {
      int response;
      switch(message) {
        case WM_COMMAND:
          switch(LOWORD(wParam)) {
            case IDM_THREAD: // create the threads
              hThread1 = (HANDLE) _beginthreadex(NULL, 0, 
                                   MyThread1, (void *) hwnd,
                                   0, &tid1);
              hThread2 = (HANDLE) _beginthreadex(NULL, 0,
                                   MyThread2, (void *) hwnd,
                                   0, &tid2);
              break;
            case IDM_PANEL: // activate control panel
              ThrdCtrlPanel(hInst, hThread1);
              ThrdCtrlPanel(hInst, hThread2);
              break;
            case IDM_EXIT:
              response = MessageBox(hwnd, "Quit the Program?",
                                    "Exit", MB_YESNO);
              if(response == IDYES) PostQuitMessage(0);
              break;
            case IDM_HELP:
              MessageBox(hwnd,
                         "F1: Help\nF2: Start Threads\nF3: Panel",
                         "Help", MB_OK);
              break;
          }
          break;
        case WM_DESTROY: // terminate the program 
          PostQuitMessage(0);
          break;
        default:
         return DefWindowProc(hwnd, message, wParam, lParam);
      }
      return 0;
    }
    // First thread.
    unsigned __stdcall MyThread1(void * param)
    {
      int i;
      HDC hdc;
      for(i=0; i<MAX; i++) {
        wsprintf(str, "Thread 1: loop # %5d ", i);
        hdc = GetDC((HWND) param);
        TextOut(hdc, 1, 1, str, lstrlen(str));
        ReleaseDC((HWND) param, hdc);
      }
      return 0;
    }
    // Second thread.
    unsigned __stdcall MyThread2(void * param)
    {
      int i;
      HDC hdc;
      for(i=0; i<MAX; i++) {
        wsprintf(str, "Thread 2: loop # %5d ", i);
        hdc = GetDC((HWND) param);
        TextOut(hdc, 1, 20, str, lstrlen(str));
        ReleaseDC((HWND) param, hdc);
      }
      return 0;
    }

    This program requires the header file thrdapp.h, shown here:

    #define IDM_THREAD      100
    #define IDM_HELP        101
    #define IDM_PANEL       102
    #define IDM_EXIT        103

    The resource file required by the program is shown here:

    #include <windows.h>
    #include "thrdapp.h"
    #include "tcp.rc"
    ThreadAppMenu MENU
    {
      POPUP "&Threads" {
        MENUITEM "&Start Threads\tF2", IDM_THREAD
        MENUITEM "&Control Panels\tF3", IDM_PANEL
        MENUITEM "E&xit\tCtrl+X", IDM_EXIT
      }
      MENUITEM "&Help", IDM_HELP
    }
    ThreadAppMenu ACCELERATORS
    {
      VK_F1, IDM_HELP, VIRTKEY
      VK_F2, IDM_THREAD, VIRTKEY
      VK_F3, IDM_PANEL, VIRTKEY
      "^X", IDM_EXIT
    }

    More C++ Articles
    More By McGraw-Hill/Osborne


       · you didn't talk much about threadID I tried doing: unsigned...
       · _beginthreadex will not allocate the memory for you. You need to dounsigned int...
     

    Buy this book now. This article is taken from chapter three of The Art of C++, written by Herbert Schildt (McGraw-Hill/Osborne, 2004; ISBN: 0072255129). Check it out at your favorite bookstore. Buy this book now.

    C++ ARTICLES

    - More Tricks to Gain Speed in Programming Con...
    - Easy and Efficient Programming for Contests
    - Preparing For Programming Contests
    - Programming Contests: Why Bother?
    - Polymorphism in C++
    - Overview of Virtual Functions
    - Inheritance in C++
    - Extending the Basic Streams in C++
    - Using Stringstreams in C++
    - Custom Stream Manipulation in C++
    - General Stream Manipulation in C++
    - Serialize Your Class into Streams in C++
    - Advanced File Handling with Streams in C++
    - File Handling and Streams in C++
    - The STL String Class







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    Stay green...Green IT