程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MFC使用多線程時請謹慎使用srand()來產生隨機數

MFC使用多線程時請謹慎使用srand()來產生隨機數

編輯:C++入門知識

本人最近寫一個小程序時遇到的問題,糾結了一兩天天,最終得以解決,現將相關情況寫在下面,希望其他遇到相同情況的同學能少走些彎路。

       實現的功能:基於基本對話框,按下開始按鈕後,在對話框內隨機繪制若干圖片,按下停止按鈕後,停止繪制圖片。

       由於在繪制圖片的時候還需要響應按鈕消息,所以我用了一個線程去實現繪制圖片這部分功能

      線程代碼如下:

     

[cpp] UINT ThreadDisplay(LPVOID param) 

    ImageInfo *pImage=(ImageInfo*)param; 
    if (pImage->m_ImagePathAry.GetSize()==0) 
    { 
        return FALSE; 
    } 
        <strong><span style="color:#ff0000;">srand(time(NULL));//</span></strong>  
    while(1) 
    {    
 
        CDC *pDC=pImage->pWnd->GetDC(); 
        CDC memDC; 
        CBitmap MemBitmap; 
        memDC.CreateCompatibleDC(NULL) 
        MemBitmap.CreateCompatibleBitmap(pDC,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top); 
        memDC.SelectObject(MemBitmap); 
        memDC.FillSolidRect(0,0,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top,RGB(255,255,255)); 
                <pre name="code" class="cpp">               <strong><span style="color:#ff0000;"> //srand(time(NULL));</span></strong> 
UINT ThreadDisplay(LPVOID param)
{
 ImageInfo *pImage=(ImageInfo*)param;
 if (pImage->m_ImagePathAry.GetSize()==0)
 {
  return FALSE;
 }
        <strong><span style="color:#ff0000;">srand(time(NULL));//</span></strong>
 while(1)
 {  

  CDC *pDC=pImage->pWnd->GetDC();
  CDC memDC;
  CBitmap MemBitmap;
  memDC.CreateCompatibleDC(NULL)
  MemBitmap.CreateCompatibleBitmap(pDC,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top);
  memDC.SelectObject(MemBitmap);
  memDC.FillSolidRect(0,0,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top,RGB(255,255,255));
                <pre name="code" class="cpp">               <strong><span style="color:#ff0000;"> //srand(time(NULL));</span></strong>Graphics graph(memDC.GetSafeHdc());int m_rand=rand()%pImage->m_ImagePathAry.GetSize();WCHAR* path=(pImage->imagepath+"\\"+pImage->m_ImagePathAry[m_rand]).AllocSysString();Image image(path);graph.DrawImage(&image,0,0,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top);pDC->BitBlt(pImag e->rc.left,pImage->rc.top,pImage->rc.right-pImage->rc.left,pImage->rc.bottom-pImage->rc.top,&memDC,0,0,SRCCOPY); pImage->pWnd->ReleaseDC(pDC);//m_rand++; DelayTime(30);//延時30毫秒}return TRUE;}

 

         線程采用的是工作線程,傳入的參數裡面有要繪制圖片的詳細信息。請大家注意紅色加粗的部分,srand(time(NULL)),之前我一直是放在whlie循環裡面,結果我雖然在線程裡面有寫了DelayTime(30)(這個函數就是網上有很多的精確延時函數,我博客裡面也有轉載),但是實際效果上,圖片的顯示間隔卻是1秒(視覺感覺上,大概1秒左右)。

         這裡面也是我一直不理解的地方,我將srand這段代碼放在while循環的外面之後發現程序就可以按照我設定的時間間隔繪圖了。這個真的很奇怪,難道是srand這個函數干擾了DelayTime延時精度?       

ps:

         我Debug的時候一直沒有發現錯誤是因為,srand是以當前時間作為seek的,而在線程裡面,雖然是在while循環裡面,但是每一次執行的時間都是不同,這也就導致了每次產生的隨機數也是不同的。

 

摘自 txg703003659的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved