C++
  Home arrow C++ arrow Page 5 - 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  
Dedicated Servers  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
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 / 139
    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++ - The Thread Control Panel


    (Page 5 of 11 )

    The code for the thread control panel is shown here. This file is called tcp.cpp.

    // A thread control panel.
    #include <map>
    #include <windows.h>
    #include "panel.h"
    using namespace std;
    const int NUMPRIORITIES = 5;
    const int OFFSET = 2;
    // Array of strings for priority list box.
    char priorities[NUMPRIORITIES][80] = {
      "Lowest",
      "Below Normal",
      "Normal",
      "Above Normal",
      "Highest"
    };
    // A Thread Control Panel Class.
    class ThrdCtrlPanel {
      // Information about the thread under control.
      struct ThreadInfo {
        HANDLE hThread; //  handle of thread
        int priority;   //  current priority
        bool suspended; //  true if suspended
        ThreadInfo(HANDLE ht, int p, bool s) {
          hThread = ht;
          priority = p;
          suspended = s;
        }
      };
      // This map holds a ThreadInfo for each
      // active thread control panel.
      static map<HWND, ThreadInfo> dialogmap;
    public:
      // Construct a control panel.
      ThrdCtrlPanel(HINSTANCE hInst, HANDLE hThrd);
      // The control panel's callback function.
      static LRESULT CALLBACK ThreadPanel(HWND hwnd, UINT message,
                             WPARAM wParam, LPARAM lParam);
    };
    // Define static member dialogmap.
    map<HWND, ThrdCtrlPanel::ThreadInfo> 
      ThrdCtrlPanel::dialogmap;
    // Create a thread control panel. ThrdCtrlPanel::ThrdCtrlPanel(HINSTANCE hInst,
                                HANDLE hThrd)
    {
      ThreadInfo ti(hThrd,
                    GetThreadPriority(hThrd)+OFFSET,
                    false);
      // Owner window is desktop.
      HWND hDialog = CreateDialog(hInst, "ThreadPanelDB",
                          NULL,
                          (DLGPROC) ThreadPanel);
      // Put info about this dialog box in the map. 
      dialogmap.insert(pair<HWND, ThreadInfo>(hDialog, ti));
      // Set the control panel's title.
      char str[80] = "Control Panel for Thread ";
      char str2[4];
      _itoa(dialogmap.size(), str2, 10);
      strcat(str, str2);
      SetWindowText(hDialog, str);
      // Offset each dialog box instance.
      MoveWindow(hDialog, 30*dialogmap.size(), 
               30*dialogmap.size(),
               300, 250, 1);
      // Update priority setting in the list box. 
      SendDlgItemMessage(hDialog, IDD_LB, LB_SETCURSEL, 
                            (WPARAM) ti.priority, 0);
      // Increase priority to ensure control. You can
      // change or remove this statement based on your
      // execution environment.
      SetThreadPriority(GetCurrentThread(),
                       THREAD_PRIORITY_ABOVE_NORMAL);
    }
    // Thread control panel dialog box callback function.
    LRESULT CALLBACK ThrdCtrlPanel::ThreadPanel(HWND hwnd,
                                          UINT message,
                                          WPARAM wParam,
                                          LPARAM lParam)
    {
      int i;
      HWND hpbRes, hpbSus, hpbTerm;
      switch(message) {
        case WM_INITDIALOG:
          // Initialize priority list box.
          for(i=0; i<NUMPRIORITIES i++) {
            SendDlgItemMessage(hwnd, IDD_LB,
                LB_ADDSTRING, 0, (LPARAM) priorities[i]);
            }
            // Set suspend and resume buttons for thread. 
            hpbSus = GetDlgItem(hwnd, IDD_SUSPEND);
            hpbRes = GetDlgItem(hwnd, IDD_RESUME);
            EnableWindow(hpbSus, true);  // enable Suspend
            EnableWindow(hpbRes, false); // disable Resume 
            return 1;
        case WM_COMMAND:
          map<HWND, ThreadInfo>::iterator p = dialogmap.find(hwnd);
        switch(LOWORD(wParam)) {
          case IDD_TERMINATE:
            TerminateThread(p->second.hThread, 0);
            // Disable Terminate button.
            hpbTerm = GetDlgItem(hwnd, IDD_TERMINATE); }
            EnableWindow(hpbTerm, false); // disable
            // Disable Suspend and Resume buttons.
            hpbSus = GetDlgItem(hwnd, IDD_SUSPEND);
            hpbRes = GetDlgItem(hwnd, IDD_RESUME);
            EnableWindow(hpbSus, false); // disable Suspend
            EnableWindow(hpbRes, false); // disable Resume
            return 1;
          case IDD_SUSPEND:
            SuspendThread(p->second.hThread);
            // Set state of the Suspend and Resume buttons.
            hpbSus = GetDlgItem(hwnd, IDD_SUSPEND);
            hpbRes = GetDlgItem(hwnd, IDD_RESUME);
            EnableWindow(hpbSus, false); // disable Suspend
            EnableWindow(hpbRes, true);  // enable Resume
            p->second.suspended = true;
            return 1;
          case IDD_RESUME:
            ResumeThread(p->second.hThread);
            // Set state of the Suspend and Resume buttons.
            hpbSus = GetDlgItem(hwnd, IDD_SUSPEND);
            hpbRes = GetDlgItem(hwnd, IDD_RESUME); /'
            EnableWindow(hpbSus, true);  // enable Suspend /'
            EnableWindow(hpbRes, false); // disable Resume
            p->second.suspended = false;
            return 1;
          case IDD_LB:
            // If a list box entry was clicked,
            // then change the priority.
            if(HIWORD(wParam)==LBN_DBLCLK) {
             p->second.priority = SendDlgItemMessage(hwnd,
                                  IDD_LB, LB_GETCURSEL,/'
                                  0, 0);
            SetThreadPriority(p->second.hThread,
                                        p->second.priority-OFFSET);
            }
            return 1;
          case IDCANCEL:
            // If thread is suspended when panel is closed,
            // then resume thread to prevent deadlock.
            if(p->second.suspended) {
               ResumeThread(p->second.hThread);
              p->second.suspended = false;
            }
            // Remove this thread from the list.
            dialogmap.erase(hwnd);
            // Close the panel.
            DestroyWindow(hwnd);?
            return 1;
            }
      }
      return 0;
    }

    The control panel requires the following resource file, called tcp.rc:

    #include <windows.h>
    #include "panel.h"
    ThreadPanelDB DIALOGEX 20, 20, 140, 110
    CAPTION "Thread Control Panel"
    STYLE WS_BORDER | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
    {
      DEFPUSHBUTTON "Done", IDCANCEL, 55, 80, 33, 14
      PUSHBUTTON "Terminate", IDD_TERMINATE, 10, 20, 42, 12 
      PUSHBUTTON "Suspend", IDD_SUSPEND, 10, 35, 42, 12
      PUSHBUTTON "Resume", IDD_RESUME, 10, 50, 42, 12
      LISTBOX IDD_LB, 65, 20, 63, 42, LBS_NOTIFY | WS_VISIBLE |
              WS_BORDER | WS_VSCROLL | WS_TABSTOP
      CTEXT "Thread Priority", IDD_TEXT1, 65, 8, 64, 10
      CTEXT "Change State", IDD_TEXT2, 0, 8, 64, 10
    }

    The control panel uses the following header file called panel.h:

    #define IDD_LB           200
    #define IDD_TERMINATE    202
    #define IDD_SUSPEND      204
    #define IDD_RESUME       206
    #define IDD_TEXT1        208
    #define IDD_TEXT2        209

    To use the thread control panel, follow these steps:

    1. Include tcp.cpp in your program.

    2. Include tcp.rc in your program’s resource file.

    3. Create the thread or threads that you want to control.

    4. Instantiate a ThrdCtrlPanel object for each thread.

    Each ThrdCtrlPanel object links a thread with a dialog box that controls it. For large projects in which multiple files need access to ThrdCtrlPanel, you will need to use a header file called tcp.h that contains the declaration for ThrdCtrlPanel. Here is tcp.h:

    // A header file for the ThrdCtrlPanel class.
    class ThrdCtrlPanel {
    public:
      // Construct a control panel.
      ThrdCtrlPanel(HINSTANCE hInst, HANDLE hThrd);
      // The control panel's callback function.
      static LRESULT CALLBACK ThreadPanel(HWND hwnd, UINT message,
                             WPARAM wParam, LPARAM lParam);
    };

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


     

    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

    - Multiplying Large Numbers with Karatsuba`s A...
    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion
    - First Steps in (C) Programming, continued
    - First Steps in (C) Programming, introduction
    - C++ Preprocessor: Always Assert Your Code Is...
    - C++ Preprocessor: The Code in the Middle
    - Programming in C
    - Temporary Variables: Runtime rvalue Detection







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway