heshuying 发表于 2006-5-16 10:48

[求助]多线程同步问题截面不能运行,为什么

<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-&gt;color==RED)<BR>            hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"RedSpeed");<BR>        else if(temp-&gt;color==GREEN)<BR>            hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"GreenSpeed");<BR>        else if(temp-&gt;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-&gt;xPos+temp-&gt;ballr)&gt;=((LPRECT)temp-&gt;rect)-&gt;right)<BR>    xadd=FALSE;<BR>   else if((temp-&gt;xPos-temp-&gt;ballr)&lt;=((LPRECT)temp-&gt;rect)-&gt;left)<BR>    xadd=TRUE;<BR>   if((temp-&gt;yPos+temp-&gt;ballr)&gt;=((LPRECT)temp-&gt;rect)-&gt;bottom)<BR>    yadd=FALSE;<BR>   else if((temp-&gt;yPos-temp-&gt;ballr)&lt;=((LPRECT)temp-&gt;rect)-&gt;top)<BR>    yadd=TRUE;<BR>   if(xadd)<BR>    temp-&gt;xPos++;<BR>   else temp-&gt;xPos--;<BR>   if(yadd)<BR>    temp-&gt;yPos++;<BR>   else temp-&gt;yPos--;<BR>   CRect rect(temp-&gt;xPos-temp-&gt;ballr-2,temp-&gt;yPos-temp-&gt;ballr-2,temp-&gt;xPos+temp-&gt;ballr+2,temp-&gt;yPos+temp-&gt;ballr+2);<BR>   InvalidateRect(temp-&gt;hWnd,rect,TRUE);<BR>   Sleep(temp-&gt;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()-&gt;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 &amp; 0xFFF0) == IDM_ABOUTBOX);<BR> ASSERT(IDM_ABOUTBOX &lt; 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-&gt;AppendMenu(MF_SEPARATOR);<BR>   pSysMenu-&gt;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)-&gt;EnableWindow(TRUE);<BR>    GetDlgItem(IDC_BUTTON_END)-&gt;EnableWindow(FALSE);</P>
<P>    GetDlgItem(IDC_SPEED_RED)-&gt;EnableWindow(FALSE);<BR>    GetDlgItem(IDC_SPEED_GREEN)-&gt;EnableWindow(FALSE);<BR>    GetDlgItem(IDC_SPEED_BLUE)-&gt;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 &amp; 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(&amp;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-&gt;SelectObject(&amp;brush);<BR>  pDC-&gt;Ellipse(m_GreenBall.xPos-((LPRECT)m_GreenBall.rect)-&gt;left-m_GreenBall.ballr,m_GreenBall.yPos-((LPRECT)m_GreenBall.rect)-&gt;top-m_GreenBall.ballr,m_GreenBall.xPos-((LPRECT)m_GreenBall.rect)-&gt;left+m_GreenBall.ballr,m_GreenBall.yPos-((LPRECT)m_GreenBall.rect)-&gt;top+m_GreenBall.ballr);<BR>  pDC-&gt;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-&gt;SelectObject(&amp;brush);<BR>  pDC-&gt;Ellipse(m_BlueBall.xPos-((LPRECT)m_BlueBall.rect)-&gt;left-m_BlueBall.ballr,m_BlueBall.yPos-((LPRECT)m_BlueBall.rect)-&gt;top-m_BlueBall.ballr,m_BlueBall.xPos-((LPRECT)m_BlueBall.rect)-&gt;left+m_BlueBall.ballr,m_BlueBall.yPos-((LPRECT)m_BlueBall.rect)-&gt;top+m_BlueBall.ballr);<BR>  pDC-&gt;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-&gt;SelectObject(&amp;brush);<BR>  pDC-&gt;Ellipse(m_RedBall.xPos-((LPRECT)m_RedBall.rect)-&gt;left-m_RedBall.ballr,m_RedBall.yPos-((LPRECT)m_RedBall.rect)-&gt;top-m_RedBall.ballr,m_RedBall.xPos-((LPRECT)m_RedBall.rect)-&gt;left+m_RedBall.ballr,m_RedBall.yPos-((LPRECT)m_RedBall.rect)-&gt;top+m_RedBall.ballr);<BR>  pDC-&gt;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)-&gt;left+m_GreenBall.ballr;<BR>  m_GreenBall.yPos=((LPRECT)m_MoveRect)-&gt;top+m_GreenBall.ballr;<BR>  m_GreenBall.rect=m_MoveRect;<BR>  m_IsGreen=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hGreenThread,&amp;code)||(code!=STILL_ACTIVE))<BR>  m_hGreenThread=CreateThread(NULL,0,BallMove,&amp;m_GreenBall,0,&amp;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)-&gt;left+m_BlueBall.ballr+50;<BR>  m_BlueBall.yPos=((LPRECT)m_MoveRect)-&gt;top+m_BlueBall.ballr+60;<BR>  m_BlueBall.rect=m_MoveRect;<BR>  m_IsBlue=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hBlueThread,&amp;code)||(code!=STILL_ACTIVE))<BR>  m_hBlueThread=CreateThread(NULL,0,BallMove,&amp;m_BlueBall,0,&amp;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)-&gt;left+m_RedBall.ballr+100;<BR>  m_RedBall.yPos=((LPRECT)m_MoveRect)-&gt;top+m_RedBall.ballr+30;<BR>  m_RedBall.rect=m_MoveRect;<BR>  m_IsRed=TRUE;<BR> }<BR> if(!GetExitCodeThread(m_hRedThread,&amp;code)||(code!=STILL_ACTIVE))<BR>  m_hRedThread=CreateThread(NULL,0,BallMove,&amp;m_RedBall,0,&amp;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)-&gt;EnableWindow(FALSE);<BR>        GetDlgItem(IDC_BUTTON_END)-&gt;EnableWindow(TRUE);<BR>         <BR>        GetDlgItem(IDC_SPEED_RED)-&gt;EnableWindow(TRUE);<BR>        GetDlgItem(IDC_SPEED_GREEN)-&gt;EnableWindow(TRUE);<BR>        GetDlgItem(IDC_SPEED_BLUE)-&gt;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,&amp;code))<BR>  if(code==STILL_ACTIVE)<BR>  {<BR>   TerminateThread(m_hGreenThread,0);<BR>   CloseHandle(m_hGreenThread);<BR>  }<BR> if(GetExitCodeThread(m_hBlueThread,&amp;code))<BR>  if(code==STILL_ACTIVE)<BR>  {<BR>   TerminateThread(m_hBlueThread,0);<BR>   CloseHandle(m_hBlueThread);<BR>  }<BR> if(GetExitCodeThread(m_hRedThread,&amp;code))<BR>  if(code==STILL_ACTIVE)<BR>  {<BR>   TerminateThread(m_hRedThread,0);<BR>   CloseHandle(m_hRedThread);<BR>  }</P>
<P>  GetDlgItem(IDC_BUTTON_START)-&gt;EnableWindow(TRUE);<BR>        GetDlgItem(IDC_BUTTON_END)-&gt;EnableWindow(FALSE);</P>
<P>        GetDlgItem(IDC_SPEED_RED)-&gt;EnableWindow(FALSE);<BR>        GetDlgItem(IDC_SPEED_GREEN)-&gt;EnableWindow(FALSE);<BR>        GetDlgItem(IDC_SPEED_BLUE)-&gt;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&amp; 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>

heshuying 发表于 2006-5-17 18:31

帮忙啊!急用啊[em08]

页: [1]

编程论坛