[求助]多线程同步问题截面不能运行,为什么
<P><FONT color=#ee3d11><FONT color=#0938f7>我在做一个多线程同步问题的程序,程序没有出现错误,但是,动态截面不能运行,偶尔出现错误,提示Sleep(sleep)中的sleep没有初始化的信息,请大家帮忙!请加我QQ190231986 给我点建议!</FONT><BR></FONT><FONT color=#ee3d11>下面是MoveDlg.cpp文件</FONT><BR>#include "stdafx.h"<BR>#include "Move.h"<BR>#include "MoveDlg.h"</P><P>#ifdef _DEBUG<BR>#define new DEBUG_NEW<BR>#undef THIS_FILE<BR>static char THIS_FILE[] = __FILE__;<BR>#endif</P>
<P>#define MAX_SPEED 50<BR>#define MIN_SPEED 5<BR>#define TIME_OUT 100<BR>#define RED 0<BR>#define GREEN 1<BR>#define BLUE 2</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////<BR>// CAboutDlg dialog used for App About<BR>DWORD WINAPI BallMove(LPVOID lpparameter)<BR> {<BR> LPINFO temp=(LPINFO)lpparameter;<BR> BOOL xadd,yadd;<BR> HANDLE hMutex;<BR> long speed;<BR> //取得相应的小求的互斥量的句柄<BR> if(temp->color==RED)<BR> hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"RedSpeed");<BR> else if(temp->color==GREEN)<BR> hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"GreenSpeed");<BR> else if(temp->color==BLUE)<BR> hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"BlueSpeed");<BR> if(hMutex==NULL)<BR> return 1;<BR> xadd=yadd=TRUE;<BR> while(TRUE)<BR> {<BR> if(WaitForSingleObject(hMutex,TIME_OUT)==WAIT_FAILED)<BR> continue;<BR> if((temp->xPos+temp->ballr)>=((LPRECT)temp->rect)->right)<BR> xadd=FALSE;<BR> else if((temp->xPos-temp->ballr)<=((LPRECT)temp->rect)->left)<BR> xadd=TRUE;<BR> if((temp->yPos+temp->ballr)>=((LPRECT)temp->rect)->bottom)<BR> yadd=FALSE;<BR> else if((temp->yPos-temp->ballr)<=((LPRECT)temp->rect)->top)<BR> yadd=TRUE;<BR> if(xadd)<BR> temp->xPos++;<BR> else temp->xPos--;<BR> if(yadd)<BR> temp->yPos++;<BR> else temp->yPos--;<BR> CRect rect(temp->xPos-temp->ballr-2,temp->yPos-temp->ballr-2,temp->xPos+temp->ballr+2,temp->yPos+temp->ballr+2);<BR> InvalidateRect(temp->hWnd,rect,TRUE);<BR> Sleep(temp->speed);<BR> ReleaseMutex(hMutex);<BR> Sleep(speed);<BR> }<BR> return 0;<BR> }<BR> HANDLE h_gRMutex;<BR> HANDLE h_gGMutex;<BR> HANDLE h_gBMutex;<BR>class CAboutDlg : public CDialog<BR>{<BR>public:<BR> CMoveDlg Create;<BR> CAboutDlg();</P>
<P>// Dialog Data<BR> //{{AFX_DATA(CAboutDlg)<BR> enum { IDD = IDD_ABOUTBOX };<BR> //}}AFX_DATA <BR> // ClassWizard generated virtual function overrides<BR> //{{AFX_VIRTUAL(CAboutDlg)<BR> protected:<BR> virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support<BR> //}}AFX_VIRTUAL</P>
<P>// Implementation<BR>protected:</P>
<P> //{{AFX_MSG(CAboutDlg)</P>
<P> //}}AFX_MSG<BR> <BR> DECLARE_MESSAGE_MAP()<BR>};</P>
<P>CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)<BR>{<BR> //{{AFX_DATA_INIT(CAboutDlg)<BR> //}}AFX_DATA_INIT</P>
<P>}</P>
<P>void CAboutDlg::DoDataExchange(CDataExchange* pDX)<BR>{<BR> CDialog::DoDataExchange(pDX);<BR> //{{AFX_DATA_MAP(CAboutDlg)<BR> //}}AFX_DATA_MAP</P>
<P>}</P>
<P>BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)<BR> //{{AFX_MSG_MAP(CAboutDlg)<BR> // No message handlers<BR> //}}AFX_MSG_MAP<BR>END_MESSAGE_MAP()</P>
<P>/////////////////////////////////////////////////////////////////////////////<BR>// CMoveDlg dialog</P>
<P>CMoveDlg::CMoveDlg(CWnd* pParent /*=NULL*/)<BR> : CDialog(CMoveDlg::IDD, pParent)<BR>{<BR> //{{AFX_DATA_INIT(CMoveDlg)<BR> // NOTE: the ClassWizard will add member initialization here<BR> //}}AFX_DATA_INIT<BR> // Note that LoadIcon does not require a subsequent DestroyIcon in Win32<BR> m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);<BR> m_IsGreen=m_IsBlue=m_IsRed=FALSE;</P>
<P> h_gRMutex=CreateMutex(NULL,FALSE,"RedSpeed");<BR> h_gGMutex=CreateMutex(NULL,FALSE,"GreenSpeed");<BR> h_gBMutex=CreateMutex(NULL,FALSE,"BlueSpeed");<BR> if((h_gRMutex==NULL)||(h_gGMutex==NULL)||(h_gBMutex==NULL))<BR> {<BR> AfxMessageBox("生成互斥量失败");<BR> CloseHandle(h_gRMutex);<BR> CloseHandle(h_gGMutex);<BR> CloseHandle(h_gBMutex);<BR> OnOK();<BR> }<BR>}</P>
<P>void CMoveDlg::DoDataExchange(CDataExchange* pDX)<BR>{<BR> CDialog::DoDataExchange(pDX);<BR> //{{AFX_DATA_MAP(CMoveDlg)<BR> DDX_Control(pDX, IDC_SPEED_RED, m_RSpeed);<BR> DDX_Control(pDX, IDC_SPEED_GREEN, m_GSpeed);<BR> DDX_Control(pDX, IDC_SPEED_BLUE, m_BSpeed);<BR> DDX_Control(pDX, IDC_MOVEBOX, m_MoveBox);<BR> //}}AFX_DATA_MAP<BR>}</P>
<P>BEGIN_MESSAGE_MAP(CMoveDlg, CDialog)<BR> //{{AFX_MSG_MAP(CMoveDlg)<BR> ON_WM_SYSCOMMAND()<BR> ON_WM_PAINT()<BR> ON_WM_QUERYDRAGICON()<BR> ON_BN_CLICKED(IDC_BUTTON_END, OnButtonEnd)<BR> ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)<BR> ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SPEED_BLUE, OnReleasedcaptureSpeedBlue)<BR> ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SPEED_GREEN, OnReleasedcaptureSpeedGreen)<BR> ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SPEED_RED, OnReleasedcaptureSpeedRed)<BR> ON_WM_CLOSE()<BR> //}}AFX_MSG_MAP<BR>END_MESSAGE_MAP()</P>
<P>/////////////////////////////////////////////////////////////////////////////<BR>// CMoveDlg message handlers</P>
<P>BOOL CMoveDlg::OnInitDialog()<BR>{<BR> CDialog::OnInitDialog();</P>
<P> // Add "About..." menu item to system menu.</P>
<P> // IDM_ABOUTBOX must be in the system command range.<BR> ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);<BR> ASSERT(IDM_ABOUTBOX < 0xF000);</P>
<P> CMenu* pSysMenu = GetSystemMenu(FALSE);<BR> if (pSysMenu != NULL)<BR> {<BR> CString strAboutMenu;<BR> strAboutMenu.LoadString(IDS_ABOUTBOX);<BR> if (!strAboutMenu.IsEmpty())<BR> {<BR> pSysMenu->AppendMenu(MF_SEPARATOR);<BR> pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);<BR> }<BR> }</P>
<P> // Set the icon for this dialog. The framework does this automatically<BR> // when the application's main window is not a dialog<BR> SetIcon(m_hIcon, TRUE); // Set big icon<BR> SetIcon(m_hIcon, FALSE); // Set small icon<BR> <BR> // TODO: Add extra initialization here<BR> m_RSpeed.SetRangeMax(MAX_SPEED);<BR> m_RSpeed.SetRangeMin(MIN_SPEED);</P>
<P> m_GSpeed.SetRangeMax(MAX_SPEED);<BR> m_GSpeed.SetRangeMin(MIN_SPEED);<BR> <BR> m_BSpeed.SetRangeMax(MAX_SPEED);<BR> m_BSpeed.SetRangeMin(MIN_SPEED); <BR> <BR> GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);<BR> GetDlgItem(IDC_BUTTON_END)->EnableWindow(FALSE);</P>
<P> GetDlgItem(IDC_SPEED_RED)->EnableWindow(FALSE);<BR> GetDlgItem(IDC_SPEED_GREEN)->EnableWindow(FALSE);<BR> GetDlgItem(IDC_SPEED_BLUE)->EnableWindow(FALSE);<BR> <BR> <BR> return TRUE; // return TRUE unless you set the focus to a control<BR>}</P>
<P>void CMoveDlg::OnSysCommand(UINT nID, LPARAM lParam)<BR>{<BR> if ((nID & 0xFFF0) == IDM_ABOUTBOX)<BR> {<BR> CAboutDlg dlgAbout;<BR> dlgAbout.DoModal();<BR> }<BR> else<BR> {<BR> CDialog::OnSysCommand(nID, lParam);<BR> }<BR>}</P>
<P>// If you add a minimize button to your dialog, you will need the code below<BR>// to draw the icon. For MFC applications using the document/view model,<BR>// this is automatically done for you by the framework.</P>
<P>void CMoveDlg::OnPaint() <BR>{<BR> if (IsIconic())<BR> {<BR> CPaintDC dc(this); // device context for painting</P>
<P> SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);</P>
<P> // Center icon in client rectangle<BR> int cxIcon = GetSystemMetrics(SM_CXICON);<BR> int cyIcon = GetSystemMetrics(SM_CYICON);<BR> CRect rect;<BR> GetClientRect(&rect);<BR> int x = (rect.Width() - cxIcon + 1) / 2;<BR> int y = (rect.Height() - cyIcon + 1) / 2;</P>
<P> // Draw the icon<BR> dc.DrawIcon(x, y, m_hIcon);<BR> }<BR> else<BR> {<BR> CDialog::OnPaint();<BR> }<BR> if(m_IsGreen)<BR> {<BR> CDC* pDC=m_MoveBox.GetDC();<BR> CBrush * poldbrush;<BR> CBrush brush(RGB(0,255,0));<BR> poldbrush=pDC->SelectObject(&brush);<BR> pDC->Ellipse(m_GreenBall.xPos-((LPRECT)m_GreenBall.rect)->left-m_GreenBall.ballr,m_GreenBall.yPos-((LPRECT)m_GreenBall.rect)->top-m_GreenBall.ballr,m_GreenBall.xPos-((LPRECT)m_GreenBall.rect)->left+m_GreenBall.ballr,m_GreenBall.yPos-((LPRECT)m_GreenBall.rect)->top+m_GreenBall.ballr);<BR> pDC->SelectObject(poldbrush);<BR> }<BR> if(m_IsBlue)<BR> {<BR> CDC* pDC=m_MoveBox.GetDC();<BR> CBrush * poldbrush;<BR> CBrush brush(RGB(0,0,255));<BR> poldbrush=pDC->SelectObject(&brush);<BR> pDC->Ellipse(m_BlueBall.xPos-((LPRECT)m_BlueBall.rect)->left-m_BlueBall.ballr,m_BlueBall.yPos-((LPRECT)m_BlueBall.rect)->top-m_BlueBall.ballr,m_BlueBall.xPos-((LPRECT)m_BlueBall.rect)->left+m_BlueBall.ballr,m_BlueBall.yPos-((LPRECT)m_BlueBall.rect)->top+m_BlueBall.ballr);<BR> pDC->SelectObject(poldbrush);<BR> }<BR> if(m_IsRed)<BR> {<BR> CDC* pDC=m_MoveBox.GetDC();<BR> CBrush * poldbrush;<BR> CBrush brush(RGB(255,0,0));<BR> poldbrush=pDC->SelectObject(&brush);<BR> pDC->Ellipse(m_RedBall.xPos-((LPRECT)m_RedBall.rect)->left-m_RedBall.ballr,m_RedBall.yPos-((LPRECT)m_RedBall.rect)->top-m_RedBall.ballr,m_RedBall.xPos-((LPRECT)m_RedBall.rect)->left+m_RedBall.ballr,m_RedBall.yPos-((LPRECT)m_RedBall.rect)->top+m_RedBall.ballr);<BR> pDC->SelectObject(poldbrush);<BR> }</P>
<P>}</P>
<P>// The system calls this to obtain the cursor to display while the user drags<BR>// the minimized window.<BR>HCURSOR CMoveDlg::OnQueryDragIcon()<BR>{<BR> return (HCURSOR) m_hIcon;<BR>}</P>
<P>void CMoveDlg::OnButtonStart() <BR>{<BR> // TODO: Add your control notification handler code here<BR> DWORD ThreadID;<BR> DWORD code;<BR> CRect rect;<BR> GetClientRect(rect);<BR> ClientToScreen(rect);<BR> m_MoveBox.GetClientRect(m_MoveRect);<BR> m_MoveBox.ClientToScreen(m_MoveRect);<BR> m_MoveRect-=rect.TopLeft();<BR> if(!m_IsGreen)<BR> {<BR> m_GreenBall.hWnd=m_hWnd;<BR> m_GreenBall.ballr=8;<BR> m_GreenBall.speed=10;<BR> m_GreenBall.xPos=((LPRECT)m_MoveRect)->left+m_GreenBall.ballr;<BR> m_GreenBall.yPos=((LPRECT)m_MoveRect)->top+m_GreenBall.ballr;<BR> m_GreenBall.rect=m_MoveRect;<BR> m_IsGreen=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hGreenThread,&code)||(code!=STILL_ACTIVE))<BR> m_hGreenThread=CreateThread(NULL,0,BallMove,&m_GreenBall,0,&ThreadID);<BR> if(m_hGreenThread==NULL)<BR> {<BR> MessageBox("Create thread Green Ball failed!");<BR> m_IsGreen=FALSE;<BR> }<BR> if(!m_IsBlue)<BR> {<BR> m_BlueBall.hWnd=m_hWnd;<BR> m_BlueBall.ballr=9;<BR> m_BlueBall.speed=20;<BR> m_BlueBall.xPos=((LPRECT)m_MoveRect)->left+m_BlueBall.ballr+50;<BR> m_BlueBall.yPos=((LPRECT)m_MoveRect)->top+m_BlueBall.ballr+60;<BR> m_BlueBall.rect=m_MoveRect;<BR> m_IsBlue=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hBlueThread,&code)||(code!=STILL_ACTIVE))<BR> m_hBlueThread=CreateThread(NULL,0,BallMove,&m_BlueBall,0,&ThreadID);<BR> if(m_hBlueThread==NULL)<BR> {<BR> MessageBox("Create thread Blue Ball failed!");<BR> m_IsBlue=FALSE;<BR> }<BR> if(!m_IsRed)<BR> {<BR> m_RedBall.hWnd=m_hWnd;<BR> m_RedBall.ballr=7;<BR> m_RedBall.speed=15;<BR> m_RedBall.xPos=((LPRECT)m_MoveRect)->left+m_RedBall.ballr+100;<BR> m_RedBall.yPos=((LPRECT)m_MoveRect)->top+m_RedBall.ballr+30;<BR> m_RedBall.rect=m_MoveRect;<BR> m_IsRed=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hRedThread,&code)||(code!=STILL_ACTIVE))<BR> m_hRedThread=CreateThread(NULL,0,BallMove,&m_RedBall,0,&ThreadID);<BR> if(m_hRedThread==NULL)<BR> {<BR> MessageBox("Create thread Red Ball failed!");<BR> m_IsRed=FALSE;<BR> }</P>
<P> GetDlgItem(IDC_BUTTON_START)->EnableWindow(FALSE);<BR> GetDlgItem(IDC_BUTTON_END)->EnableWindow(TRUE);<BR> <BR> GetDlgItem(IDC_SPEED_RED)->EnableWindow(TRUE);<BR> GetDlgItem(IDC_SPEED_GREEN)->EnableWindow(TRUE);<BR> GetDlgItem(IDC_SPEED_BLUE)->EnableWindow(TRUE); </P>
<P>}<BR>void CMoveDlg::OnButtonEnd() <BR>{<BR> // TODO: Add your control notification handler code here<BR> DWORD code;<BR> if(GetExitCodeThread(m_hGreenThread,&code))<BR> if(code==STILL_ACTIVE)<BR> {<BR> TerminateThread(m_hGreenThread,0);<BR> CloseHandle(m_hGreenThread);<BR> }<BR> if(GetExitCodeThread(m_hBlueThread,&code))<BR> if(code==STILL_ACTIVE)<BR> {<BR> TerminateThread(m_hBlueThread,0);<BR> CloseHandle(m_hBlueThread);<BR> }<BR> if(GetExitCodeThread(m_hRedThread,&code))<BR> if(code==STILL_ACTIVE)<BR> {<BR> TerminateThread(m_hRedThread,0);<BR> CloseHandle(m_hRedThread);<BR> }</P>
<P> GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);<BR> GetDlgItem(IDC_BUTTON_END)->EnableWindow(FALSE);</P>
<P> GetDlgItem(IDC_SPEED_RED)->EnableWindow(FALSE);<BR> GetDlgItem(IDC_SPEED_GREEN)->EnableWindow(FALSE);<BR> GetDlgItem(IDC_SPEED_BLUE)->EnableWindow(FALSE);</P>
<P>}</P>
<P><BR>void CMoveDlg::OnClose() <BR>{<BR> // TODO: Add your message handler code here and/or call default<BR> OnButtonEnd();<BR> CloseHandle(h_gRMutex);<BR> CloseHandle(h_gGMutex);<BR> CloseHandle(h_gBMutex);<BR> <BR> CDialog::OnClose();<BR>}<BR>BOOL CMoveDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) <BR>{<BR> // TODO: Add your specialized code here and/or call the base class</P>
<P> <BR> return CDialog::Create(IDD, pParentWnd);<BR>}<BR> <BR>void CMoveDlg::OnReleasedcaptureSpeedBlue(NMHDR* pNMHDR, LRESULT* pResult) <BR>{<BR> // TODO: Add your control notification handler code here<BR> if(WaitForSingleObject(h_gBMutex,TIME_OUT)!=WAIT_FAILED)<BR> {<BR> m_BlueBall.speed=MAX_SPEED-m_BSpeed.GetPos();<BR> ReleaseMutex(h_gBMutex);<BR> }<BR> <BR> *pResult = 0;<BR>}</P>
<P>void CMoveDlg::OnReleasedcaptureSpeedGreen(NMHDR* pNMHDR, LRESULT* pResult) <BR>{<BR> // TODO: Add your control notification handler code here<BR> if(WaitForSingleObject(h_gGMutex,TIME_OUT)!=WAIT_FAILED)<BR> {<BR> m_GreenBall.speed=MAX_SPEED-m_GSpeed.GetPos();<BR> ReleaseMutex(h_gGMutex);<BR> }<BR> <BR> *pResult = 0;<BR>}</P>
<P>void CMoveDlg::OnReleasedcaptureSpeedRed(NMHDR* pNMHDR, LRESULT* pResult) <BR>{<BR> // TODO: Add your control notification handler code here<BR> if(WaitForSingleObject(h_gRMutex,TIME_OUT)!=WAIT_FAILED)<BR> {</P>
<P> m_RedBall.speed=MAX_SPEED-m_RSpeed.GetPos();<BR> ReleaseMutex(h_gRMutex);<BR> }<BR> <BR> *pResult = 0;<BR>}</P>
页:
[1]
