多线程求PI

 

 原创链接:多线程求PI

工程名:RollingCastPI

类型:基于对话框的MFC程序

编译器:VC++ 6.0

功能:主线程进行控制后台线程  开始/暂停/继续/停止  计算输出PI,控制输出速度,位数.

源文件:


 

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__06C1326B_158A_46FE_BD0B_50BD680BDB8E__INCLUDED_)
#define AFX_STDAFX_H__06C1326B_158A_46FE_BD0B_50BD680BDB8E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN  // Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>  // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>   // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//添加 头文件
#include <afxmt.h>  //CEvent 事件类型
#include "TypeConvert.h"
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__06C1326B_158A_46FE_BD0B_50BD680BDB8E__INCLUDED_)


 


                                                         RollingCastPIDlg是主对话框类


 

// RollingCastPIDlg.h : header file
//
#if !defined(AFX_ROLLINGCASTPIDLG_H__D74F0B2D_EA2B_4F4D_9232_0180FDCABBB5__INCLUDED_)
#define AFX_ROLLINGCASTPIDLG_H__D74F0B2D_EA2B_4F4D_9232_0180FDCABBB5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/
// CRollingCastPIDlg dialog
class CRollingCastPIDlg : public CDialog
{
// Construction
public:
 CRollingCastPIDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
 //{{AFX_DATA(CRollingCastPIDlg)
 enum { IDD = IDD_ROLLINGCASTPI_DIALOG };
 CSliderCtrl m_SpeedSlider;
 CComboBox m_UpLimitCombox;
 CListCtrl m_PiList;
 CListCtrl m_ThreadInforList;
 CButton m_StopButton;
 CButton m_PauseButton;
 CButton m_StartButton;
 //}}AFX_DATA
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CRollingCastPIDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL
// Implementation
protected:
 HICON m_hIcon;
 // Generated message map functions
 //{{AFX_MSG(CRollingCastPIDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnStartButton();
 afx_msg void OnPauseButton();
 afx_msg void OnStopButton();
 afx_msg void OnCustomdrawSpeedSlider(NMHDR* pNMHDR, LRESULT* pResult);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ROLLINGCASTPIDLG_H__D74F0B2D_EA2B_4F4D_9232_0180FDCABBB5__INCLUDED_)



// RollingCastPIDlg.cpp : implementation file
//
#include "stdafx.h"
#include "RollingCastPI.h"
#include "RollingCastPIDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
//         全局 变量
/
#define NCOUNT 240000
//事件句柄
CEvent g_StartEvent,  /*开始*/
   g_PauseEvent,  /*暂停*/
   g_ContinueEvent, /*继续*/
   g_StopEvent;   /*停止*/
//PI已求位数 计数器,
/* 为保证编译优化打开的情况下,
 * 计数器不被放在寄存器中而设置为volatile(易失)变量
 * 若放在寄存器中,主线程对它的修改,在辅线程中无影响*/ 
volatile long g_PiCount=0;
//小数点后位数设定
long g_MaxPoint=1000;
//输出延迟时间,单位/ms
int g_TimeDelay=0;
//线程信息输出
CListCtrl* g_ThreadInforList;
volatile int g_ThreadInforCount=0;
//按钮控制
CButton* g_StartButton;
CButton* g_PauseButton;
CButton* g_StopButton;
//输出控件
CListCtrl* g_PiList;
/
//         全局 函数
/
/*
 * 输出辅助线程信息
 */
void PrintList(CString str,CListCtrl& list,volatile int& curCount)
{
 CSize size;
 size.cx=0;
 size.cy=30;
 list.InsertItem(curCount++,str);
 list.Scroll(size);
}
/*
 * 计算PI线程函数
 */
UINT ComputePIThread(LPVOID pParam)
{
 if(WaitForSingleObject(g_StartEvent,INFINITE)==WAIT_OBJECT_0)//阻塞等待 开始事件
 {
   g_StopEvent.ResetEvent();             //清除 开始事件 信号
   g_PauseButton->EnableWindow(true);
   g_StopButton->EnableWindow(true);
   g_StartButton->EnableWindow(FALSE);
   PrintList("线程开始->>",*g_ThreadInforList,g_ThreadInforCount);
 } 
 //计算输出PI
 int temp;
 long   a=10000,b=0,c=NCOUNT,d=0,e=0,f[NCOUNT+1],g=0; 
 int row=-1,column=0;
 CSize size;
 size.cx=0;size.cy=30;
 while(g_PiCount<g_MaxPoint)
 {
   //求PI算法   
   while(b <c) 
    f[b++]=a/5;  
   while(c> 0)
   {    
    d=0;   g=c*2; b=c; 
    while(1)
    { 
     d+=f[b]*a;   f[b]=d%--g; 
     d/=g--;         b--;   
     if(b)   
      d*=b;   
     else   
      break; 
    }
    temp=e+d/a;
    e=d%a; 
    c-=14;
    //在这里分解成单个的
    CString singleWord;    
    for(int div=1000;div>=1;div/=10)
    {
     //到达指定数目,停止
     if(g_PiCount>=g_MaxPoint)
      goto PIEnd;
     singleWord=TypeConvert::NumberToString(int(temp/div));
     temp%=div;
     //每输出15个换行
     if((g_PiCount%15)==0)
     {
      row++;
      g_PiList->InsertItem(row,singleWord);
      g_PiCount++;
      g_PiList->Scroll(size);
     }
     else
     {
      g_PiList->SetItemText(row,g_PiCount%15,singleWord); 
      g_PiCount++;
     }
     //控制延时为g_TimeDelay
     Sleep(g_TimeDelay);
     //事件等待
     if(WaitForSingleObject(g_StopEvent,0)==WAIT_OBJECT_0)  //非阻塞等待 停止事件
     {
      ResetEvent(g_StopEvent);             //清除停止事件 信号
      PrintList("线程结束!!!(您按了停止)",*g_ThreadInforList,g_ThreadInforCount);
      goto ForceEnd;
     }
     if(WaitForSingleObject(g_PauseEvent,0)==WAIT_OBJECT_0)  //非阻塞等待 暂停事件
     {
      ResetEvent(g_PauseEvent);             //清除 暂停事件 信号
      g_PauseButton->SetWindowText("继续");
      g_StopButton->EnableWindow(FALSE);
      PrintList("线程挂起...(等待继续事件)",*g_ThreadInforList,g_ThreadInforCount);
      WaitForSingleObject(g_ContinueEvent,INFINITE);//阻塞等待 继续事件
      ResetEvent(g_ContinueEvent);       //清除 继续事件 信号
      g_PauseButton->SetWindowText("暂停");
      g_StopButton->EnableWindow(true);
      PrintList("线程恢复->(继续事件发生)",*g_ThreadInforList,g_ThreadInforCount);
     }
     //end of 事件等待
    }        
   }
   //end of 计算输出PI 
 }
PIEnd:
 PrintList("线程结束。||(计算完成)",*g_ThreadInforList,g_ThreadInforCount);
ForceEnd:
 g_PauseButton->EnableWindow(FALSE);
 g_StopButton->EnableWindow(FALSE);
 g_StartButton->EnableWindow(true);
 return 0;
}
/
//      end of 全局 声明
/
/
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
 CAboutDlg();
// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL
// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CRollingCastPIDlg dialog
CRollingCastPIDlg::CRollingCastPIDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CRollingCastPIDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CRollingCastPIDlg)
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CRollingCastPIDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CRollingCastPIDlg)
 DDX_Control(pDX, IDC_SPEED_SLIDER, m_SpeedSlider);
 DDX_Control(pDX, IDC_UPLIMIT_COMBO, m_UpLimitCombox);
 DDX_Control(pDX, IDC_PI_LIST, m_PiList);
 DDX_Control(pDX, IDC_THREAD_LIST, m_ThreadInforList);
 DDX_Control(pDX, IDC_STOP_BUTTON, m_StopButton);
 DDX_Control(pDX, IDC_PAUSE_BUTTON, m_PauseButton);
 DDX_Control(pDX, IDC_START_BUTTON, m_StartButton);
 //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRollingCastPIDlg, CDialog)
 //{{AFX_MSG_MAP(CRollingCastPIDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_START_BUTTON, OnStartButton)
 ON_BN_CLICKED(IDC_PAUSE_BUTTON, OnPauseButton)
 ON_BN_CLICKED(IDC_STOP_BUTTON, OnStopButton)
 ON_NOTIFY(NM_CUSTOMDRAW, IDC_SPEED_SLIDER, OnCustomdrawSpeedSlider)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CRollingCastPIDlg message handlers
BOOL CRollingCastPIDlg::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
 
 /*
  * 窗口初始化
  */ 
 //线程信息列表框
 g_ThreadInforList=&m_ThreadInforList;
 g_ThreadInforList->InsertColumn(0,"辅助线程信息",NULL,200);
 //按钮控制
 g_StartButton=&m_StartButton;
 g_PauseButton=&m_PauseButton;
 g_StopButton=&m_StopButton;
 g_PauseButton->EnableWindow(false);
 g_StopButton->EnableWindow(false); 
 //PI显示控件
 g_PiList=&m_PiList;
 g_PiList->SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_ONECLICKACTIVATE);
 for(int i=0;i<15;i++)
  g_PiList->InsertColumn(i,TypeConvert::NumberToString(1+i),LVCFMT_LEFT,24);
 //速度控制
 m_SpeedSlider.SetRange(0,10,FALSE);
 return TRUE;  // return TRUE  unless you set the focus to a control
}
void CRollingCastPIDlg::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 CRollingCastPIDlg::OnPaint() 
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (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 to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CRollingCastPIDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}
/*/
 *    开始
 /*/
void CRollingCastPIDlg::OnStartButton() 
{
 //条件初始化
 g_PiCount=0;
 CString smax;
 m_UpLimitCombox.GetWindowText(smax);
 smax.TrimLeft();smax.TrimRight();
 g_MaxPoint=atoi(smax);
 m_PiList.DeleteAllItems();
 //开始计算线程
 AfxBeginThread(ComputePIThread,GetSafeHwnd()); 
 //开始事件
 SetEvent(g_StartEvent);  
}
/*/
 *    暂停
 /*/
void CRollingCastPIDlg::OnPauseButton() 
{ 
 CString text;
 m_PauseButton.GetWindowText(text);
 if(text=="暂停")
  SetEvent(g_PauseEvent);  //暂停事件
 else
  SetEvent(g_ContinueEvent);//继续事件
 UpdateData(false);
}
/*/
 *    停止
 /*/
void CRollingCastPIDlg::OnStopButton() 
{ 
 SetEvent(g_StopEvent);   //停止事件
}
/*
 * 调节Slider时响延时改变
 */
void CRollingCastPIDlg::OnCustomdrawSpeedSlider(NMHDR* pNMHDR, LRESULT* pResult) 
{
 g_TimeDelay=m_SpeedSlider.GetPos()*100;
 *pResult = 0;
}


 


 

                                 TypeConvert是我自己写的类,封装了一些静态的用于类型转换的法方法


 

// TypeConvert.h: interface for the TypeConvert class.
//
//
#if !defined(AFX_TYPECONVERT_H__5E25438A_748A_4457_8B8A_6B19347C7A82__INCLUDED_)
#define AFX_TYPECONVERT_H__5E25438A_748A_4457_8B8A_6B19347C7A82__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/*/
 *   类型转换类
 *//
class TypeConvert  
{
public:
 TypeConvert();
 virtual ~TypeConvert();
 //数值型->字符串
 static CString NumberToString(int num);        // int
 static CString NumberToString(float fNum,int nPoint=0);  // float
 static CString NumberToString(double dNum,int nPoint=0);// double
 //字符串->char数组指针
 static char* StringToChars(CString string); 
};
#endif // !defined(AFX_TYPECONVERT_H__5E25438A_748A_4457_8B8A_6B19347C7A82__INCLUDED_)



// TypeConvert.cpp: implementation of the TypeConvert class.
//
//
#include "stdafx.h"
#include "RollingCastPI.h"
#include "TypeConvert.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
TypeConvert::TypeConvert()
{
}
TypeConvert::~TypeConvert()
{
}
/*/
 * 数值型->字符串
 /*/
// int->CString
CString TypeConvert::NumberToString(int num)
{
 CString stringNum;
 stringNum.Format("%d",num);
 return stringNum;
}
// float->CString
CString TypeConvert::NumberToString(float fNum,int nPoint/*=0*/)
{
 CString stringNum; 
 if(nPoint!=0)
 {
  CString point;
  point.Format("%d",nPoint);
  point="%."+point+"f";
  stringNum.Format(point,fNum,nPoint);
 }
 else
  stringNum.Format("%f",fNum); 
 return stringNum;
}
// double->CString
CString TypeConvert::NumberToString(double dNum,int nPoint/*=0*/)
{
 CString stringNum; 
 if(nPoint!=0)
 {
  CString point;
  point.Format("%d",nPoint);
  point="%."+point+"lf";
  stringNum.Format(point,dNum,nPoint);
 }
 else
  stringNum.Format("%lf",dNum); 
 return stringNum;
}
/*/
 * 字符串->char数组指针
 /*/
char* TypeConvert::StringToChars(CString string)
{
 int n=string.GetLength();
 char * chars=new char[n+1];
 for(int i=0;i<n;i++)
  chars[i]=string.GetAt(i);
 chars[i]=0;
 return chars;
}


 


                                                                        the end


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游戏AI开发者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值