Software & Finance





Visual C++ - Multi threading using _beginthread and _beginthreadex





Multithreading are very interesting part of programming languages. Visual C++ offers many ways to support  multithreading. I have given here a very simple way to create thread using _beginthread and _beginthreadex.



Source Code


// MultiThreadSample1Dlg.cpp : implementation file

//

 

#include "stdafx.h"

#include <vector>

#include "process.h"

#include "MultiThreadSample1.h"

#include "MultiThreadSample1Dlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

 

// CAboutDlg dialog used for App About

 

class CAboutDlg : public CDialog

{

public:

      CAboutDlg();

 

// Dialog Data

      enum { IDD = IDD_ABOUTBOX };

 

      protected:

      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

 

// Implementation

protected:

      DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

 

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

      CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

 

 

// CMultiThreadSample1Dlg dialog

 

 

 

 

CMultiThreadSample1Dlg::CMultiThreadSample1Dlg(CWnd* pParent /*=NULL*/)

      : CDialog(CMultiThreadSample1Dlg::IDD, pParent)

{

      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CMultiThreadSample1Dlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    DDX_Control(pDX, IDC_LIST2, m_listCtrl);

}

 

BEGIN_MESSAGE_MAP(CMultiThreadSample1Dlg, CDialog)

      ON_WM_SYSCOMMAND()

      ON_WM_PAINT()

      ON_WM_QUERYDRAGICON()

      //}}AFX_MSG_MAP

    ON_BN_CLICKED(IDOK, &CMultiThreadSample1Dlg::OnBnClickedOk)

    ON_BN_CLICKED(IDCANCEL, &CMultiThreadSample1Dlg::OnBnClickedCancel)

END_MESSAGE_MAP()

 

 

// CMultiThreadSample1Dlg message handlers

 

BOOL CMultiThreadSample1Dlg::OnInitDialog()

{

      CDialog::OnInitDialog();

 

      // Add "About..." menu item to system menu.

 

      // IDM_ABOUTBOX must be in the system command range.

      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

      ASSERT(IDM_ABOUTBOX < 0xF000);

 

      CMenu* pSysMenu = GetSystemMenu(FALSE);

      if (pSysMenu != NULL)

      {

            CString strAboutMenu;

            strAboutMenu.LoadString(IDS_ABOUTBOX);

            if (!strAboutMenu.IsEmpty())

            {

                  pSysMenu->AppendMenu(MF_SEPARATOR);

                  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

            }

      }

 

      // Set the icon for this dialog.  The framework does this automatically

      //  when the application's main window is not a dialog

      SetIcon(m_hIcon, TRUE);             // Set big icon

      SetIcon(m_hIcon, FALSE);            // Set small icon

 

      m_listCtrl.InsertColumn( 0, _T("Thread Index"));

      m_listCtrl.InsertColumn( 1, _T("Type"));

      m_listCtrl.InsertColumn( 2, _T("Value"));

      m_listCtrl.SetColumnWidth( 0, 100);

      m_listCtrl.SetColumnWidth( 1, 80);

      m_listCtrl.SetColumnWidth( 2, 155);

 

      return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CMultiThreadSample1Dlg::OnSysCommand(UINT nID, LPARAM lParam)

{

      if ((nID & 0xFFF0) == IDM_ABOUTBOX)

      {

            CAboutDlg dlgAbout;

            dlgAbout.DoModal();

      }

      else

      {

            CDialog::OnSysCommand(nID, lParam);

      }

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

 

void CMultiThreadSample1Dlg::OnPaint()

{

      if (IsIconic())

      {

            CPaintDC dc(this); // device context for painting

 

            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

            // Center icon in client rectangle

            int cxIcon = GetSystemMetrics(SM_CXICON);

            int cyIcon = GetSystemMetrics(SM_CYICON);

            CRect rect;

            GetClientRect(&rect);

            int x = (rect.Width() - cxIcon + 1) / 2;

            int y = (rect.Height() - cyIcon + 1) / 2;

 

            // Draw the icon

            dc.DrawIcon(x, y, m_hIcon);

      }

      else

      {

            CDialog::OnPaint();

      }

}

 

// The system calls this function to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CMultiThreadSample1Dlg::OnQueryDragIcon()

{

      return static_cast<HCURSOR>(m_hIcon);

}

 

static int index = 0;

 

static void f(void *p)

{

    CMultiThreadSample1Dlg *pDlg = reinterpret_cast<CMultiThreadSample1Dlg*>(p);

    pDlg->ThreadProc(index++);

}

 

static unsigned int __stdcall f2(void *p)

{

    CMultiThreadSample1Dlg *pDlg = reinterpret_cast<CMultiThreadSample1Dlg*>(p);

    pDlg->ThreadProc(index++);

    return 0;

}

 

void CMultiThreadSample1Dlg::ThreadProc(int idx)

{

    wchar_t buf[32];

    LV_ITEM lvitem;

      lvitem.iItem = idx;

      lvitem.mask = 0;

      lvitem.iSubItem = 0;

      m_listCtrl.InsertItem( &lvitem);

    wsprintf(buf, _T("Thread : %d"), idx + 1);

    m_listCtrl.SetItemText( idx, 0, buf);

      m_listCtrl.SetItemText( idx, 1, _T("Counter"));

 

   

    for(int i = 1; ;i++)

    {

        wsprintf(buf, _T("%d"), i);

        m_listCtrl.SetItemText( idx, 2, buf);

        ::Sleep(100);

    }

}

 

std::vector<HANDLE> hlist1, hlist2;

void CMultiThreadSample1Dlg::OnBnClickedOk()

{

    HANDLE h = (HANDLE) ::_beginthread(f, 0, (void*) this);

    hlist1.push_back(h);

    unsigned int addr = 0;

    HANDLE h2 = (HANDLE)::_beginthreadex(NULL, 0, f2, (void*) this, 0, &addr);

    hlist2.push_back(h2);

}

 

void CMultiThreadSample1Dlg::OnBnClickedCancel()

{

    for(int i = 0; i < hlist1.size(); i++)

        ::CloseHandle(hlist1[i]);

    for(int i = 0; i < hlist2.size(); i++)

        ::CloseHandle(hlist2[i]);

    OnCancel();

}

 

Click here to download the complete project and executable


Output