10421|21

85

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

程序运行一段时间就死机!有代码 [复制链接]

最近做一个CE下的程序,对系统稳定性要求很高,能长时间开机工作(运行几个月应该没问题).可是我这程序运行1个小时左右就会死掉.前几天是有内存泄露,但我现在把这问题解决了.可是还是不好用.我先说下我的思路:
我这个要求能播放图片,我在程序中设置了两个线程A,B;A不停的读一个节目播放列表文件,每次读一个播放单元,B中不停检测时候有播放单元,如果有则启动一个线程C,然后把C中的图片BMP1,BITBLT到另一个图片上,贴出来,而C中做的工作是把播放单元的图片读出来,并按一定动作画到图片BMP1上,.当C中动作完成后退出,这个时候B就把播放单元信息释放掉.等待新的播放单元,而A检测到播放单元释放后会读新的播放单元.
这个就是我的思路.下面是部分代码,大家帮忙找找原因 谢谢

DWORD WINAPI Thread_ReadPlayList(LPVOID lpParam)
{
        FILE * f;
        f=_wfopen(PlayListPath,L"rb");
        if(NULL==f)
        {
                //传送错误信息:文件打开失败
                MessageBoxW(NULL,L"Open file false",L"",MB_OK);
                return 1;
        }
        int nWidth,nHeight;
        int nTemp,nUsedLabelItem;
        Arm_Label_Node *pLabel;
        fread(&nWidth,1,sizeof(int),f);
        fread(&nHeight,1,sizeof(int),f);
        if(nWidth!=g_nScreenWidth||nHeight!=g_nScreenHeight)
        {
                //传送错误信息:节目列表错误,不是当前屏幕的节目列表
                MessageBoxW(NULL,L"width && Heiht false",L"",MB_OK);
                return 1;
        }
        while(!g_bStop)
        {//{{{
                while(0!=g_PlayNode.nType)//非空结点
                {
                        Sleep(1);
                }
                WaitForSingleObject(hMutexNode,INFINITE);
READNEXTINFO:
                fread(&nTemp,1,sizeof(int),f);

                CString str;
                str.Format(L"nTemp=%d",nTemp);
               
                if(feof(f))
                {
                        fseek(f,8,SEEK_SET);
                        goto READNEXTINFO;
                }
                switch(nTemp)
                {
                case CLOCK_Type:
                        g_pClockNode=(Arm_Clock_SetInfo *)malloc(sizeof(Arm_Clock_SetInfo));
                        fread(g_pClockNode,1,sizeof(Arm_Clock_SetInfo),f);
                        hClockFont=CreateFontIndirect(&g_pClockNode->logFont);
                        break;
                case PIC_Type:
                        g_PlayNode.nType=PIC_Type;
                        g_PlayNode.pPointer=malloc(sizeof(Arm_Pic_SetInfo));
                        fread(g_PlayNode.pPointer,1,sizeof(Arm_Pic_SetInfo),f);
                        g_PlayNode.PathName=
                                (TCHAR *)malloc(((Arm_Pic_SetInfo *)g_PlayNode.pPointer)->nPathLength*sizeof(TCHAR));
                        fread(g_PlayNode.PathName,
                                ((Arm_Pic_SetInfo *)g_PlayNode.pPointer)->nPathLength,
                                sizeof(TCHAR),f);
                        break;
                case LABEL_Type:
               
                        if(NULL==g_pLabelNode)
                        {
                                g_pLabelNode=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));
                                pLabel=g_pLabelNode;
                        }else
                        {
                                pLabel=g_pLabelNode;
                                while(NULL!=pLabel->next)
                                        pLabel=pLabel->next;
                                pLabel->next=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));
                                pLabel=pLabel->next;
                        }
                        pLabel->next=NULL;
                        pLabel->pArm_Label_SetInfo=(Arm_Label_SetInfo *)
                                malloc(sizeof(Arm_Label_SetInfo));
                        fread(pLabel->pArm_Label_SetInfo,1,sizeof(Arm_Label_SetInfo),f);
                        fread(pLabel->tContent,pLabel->pArm_Label_SetInfo->nContentLength,sizeof(TCHAR),f);
                        hLabelFont[nUsedLabelItem++]=CreateFontIndirect(&pLabel->pArm_Label_SetInfo->logFont);
                        goto READNEXTINFO;
                        break;
                case NEWNODE:
                        if(1)
                        {
                                nUsedLabelItem=0;
                        for(int i=0;i                         {
                                if(NULL!=hLabelFont)
                                {
                                        int nRes=DeleteObject(hLabelFont);
                                        hLabelFont=NULL;
                                        if(0==nRes)
                                                MessageBoxW(NULL,L"DeleteObject hLabelFont",L"ERROR",MB_OK);
                                }
                        }
                        if(NULL!=hClockFont)
                        {
                                int nRes=DeleteObject(hClockFont);
                                hClockFont=NULL;
                                if(0==nRes)
                                        MessageBoxW(NULL,L"DeleteObject hClockFont",L"Error",MB_OK);
                        }
                        }
                        while(NULL!=g_pLabelNode)
                        {
                                pLabel=g_pLabelNode->next;
                                free(g_pLabelNode->pArm_Label_SetInfo);
                                free(g_pLabelNode);
                                g_pLabelNode=pLabel;
                        }
                        if(NULL!=g_pClockNode)
                                free(g_pClockNode);
                        g_pClockNode=NULL;
                        g_pLabelNode=NULL;
                case ENDNODE:
        //                MessageBoxW(NULL,L"EndNode",L"ReadPlayList",MB_OK);
                        goto READNEXTINFO;
                        break;
                }
                ReleaseMutex(hMutexNode);
        }//}}}
        //检查未释放资源,进行释放
        return 1;
}
DWORD WINAPI Thread_Play(LPVOID lpParam)
{
        HDC hdc=::GetDC(g_hWnd);
        HANDLE handle;
        Arm_Label_Node *pLabel;
        while(!g_bStop)
        {//{{{
                while(0==g_PlayNode.nType)
                {
                        Sleep(1);
                }
                WaitForSingleObject(hMutexNode,INFINITE);
                switch(g_PlayNode.nType)
                {
                case PIC_Type:
                        g_bThreadStop=FALSE;
                        //启动一个图片线程
                        handle=CreateThread(NULL,0,Thread_PlayPic,NULL,0,NULL);
                        CloseHandle(handle);
                        break;
                }
                while(!g_bStop&&!g_bThreadStop)
                {
                        BitBlt(g_hTopDC,0,0,g_nScreenWidth,g_nScreenHeight,g_hMiddleDC,0,0,SRCCOPY);
                        pLabel=g_pLabelNode;
                        int nItem=0;
                        while(NULL!=pLabel)
                        {
                                DrawLabel(pLabel,nItem++);                       
                                pLabel=pLabel->next;
                        }
                                if(NULL!=g_pClockNode)
                                DrawClock(g_pClockNode);
                        BitBlt(hdc,0,0,g_nScreenWidth,g_nScreenHeight,g_hTopDC,0,0,SRCCOPY);
                        Sleep(5);
                }
                g_PlayNode.nType=0;
                free(g_PlayNode.pPointer);
                free(g_PlayNode.PathName);
                ReleaseMutex(hMutexNode);
        }//}}}
        return 1;
}
DWORD WINAPI Thread_PlayPic(LPVOID lpParam)
{
        CIImage mage;
        CString strPath;
        strPath=PicPathExtent;
        strPath+=g_PlayNode.PathName;
        mage.Open(strPath);
        mage.Draw(g_hIImageDC,0,0,g_nScreenWidth,g_nScreenHeight,0);
        int i=0;
        while(1)
        {
                BitBlt(g_hMiddleDC,0,0,i,g_nScreenHeight,g_hIImageDC,g_nScreenWidth-i,0,SRCCOPY);
                Sleep(5);
                i++;
                if(i>=g_nScreenWidth)
                        break;
        }
        g_bThreadStop=TRUE;       
        return 1;
}

最新回复

TO:nbcool 哦.知道了. TO 大家: 另外通过前面各位高手的指导,我把我程序总体结构改了下,下面是主体代码,大家看看这会问题多不?还有个问题就是,我发现我程序死掉可能不是我程序的事.我这边把开发板打开 过了一个晚上,今天一看 也死掉了.现在我正研究是我内核定制的事,还是 硬件问题.不过还是请大家帮我看看下面程序的结构,以前感觉我这程序没什么问题了。 可是通过这个帖子,我发现我还有很多不足,希望各位能帮我多找点问题,我会努力改进的 DWORD WINAPI Thread_ReadPlayList(LPVOID lpParam) {         HANDLE        hFileHandle;         int nWidth,nHeight;         BOOL        bRes;         DWORD        dwReadByte;         int nTemp,nUsedLabelItem;         hFileHandle=CreateFile(PlayListPath,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);         if(INVALID_HANDLE_VALUE==hFileHandle)         {MessageErrorBox(GetLastError(),L"Faile Open File");}                 bRes=ReadFile(hFileHandle,&nWidth,sizeof(int),&dwReadByte,NULL);         if(FALSE==bRes)         {MessageErrorBox(GetLastError(),L"Read File");}         bRes=ReadFile(hFileHandle,&nHeight,sizeof(int),&dwReadByte,NULL);         if(FALSE==bRes)         {MessageErrorBox(GetLastError(),L"Read File");}         if(nWidth!=g_nScreenWidth||nHeight!=g_nScreenHeight)         {                 //传送错误信息:节目列表错误,不是当前屏幕的节目列表                 MessageBoxW(NULL,L"传输的节目列表文件错误",L"Error",MB_OK);                 return 1;         }         while(!g_bStop)         {                 bRes=ReadFile(hFileHandle,&nTemp,sizeof(int),&dwReadByte,NULL);                 if(FALSE==bRes)                         {MessageErrorBox(GetLastError(),L"Read File");}                                 if(0==dwReadByte)//文件结束                 {                         bRes=CloseHandle(hFileHandle);                         if(FALSE==bRes)                                 MessageErrorBox(GetLastError(),L"CloseFile");                         {//-----------                                 hFileHandle=CreateFile(PlayListPath,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);                                 if(INVALID_HANDLE_VALUE==hFileHandle)                                 {MessageErrorBox(GetLastError(),L"Faile Open File");}                                         bRes=ReadFile(hFileHandle,&nWidth,sizeof(int),&dwReadByte,NULL);                                 if(FALSE==bRes)                                 {MessageErrorBox(GetLastError(),L"Read File");}                                 bRes=ReadFile(hFileHandle,&nHeight,sizeof(int),&dwReadByte,NULL);                                 if(FALSE==bRes)                                 {MessageErrorBox(GetLastError(),L"Read File");}                         }//-----------                 }                 switch(nTemp)                 {                 case CLOCK_Type:                         Thread_Switch_Clock_Type(hFileHandle);                                        continue;                         break;                 case PIC_Type:                         Thread_Switch_Pic_Type(hFileHandle);                         break;                 case LABEL_Type:                         Thread_Switch_Label_Type(hFileHandle,nUsedLabelItem);                         continue;                         break;                 case NEWNODE:                         Thread_Switch_NewNode(nUsedLabelItem);                                case ENDNODE:                         continue;                         break;                 }         }//}}}         //检查未释放资源,进行释放         return 1; void MessageErrorBox(int nError,CString strError) {         CString str;         str.Format(L"%d",nError);         MessageBoxW(NULL,str,strError,MB_OK); } void Thread_Switch_Clock_Type(HANDLE hFileHandle) {         BOOL bRes;         DWORD dwReadByte;         g_pClockNode=(Arm_Clock_SetInfo *)malloc(sizeof(Arm_Clock_SetInfo));         if(g_pClockNode==NULL)                 MessageErrorBox(-1,L"Malloc");         bRes=ReadFile(hFileHandle,g_pClockNode,sizeof(Arm_Clock_SetInfo),&dwReadByte,NULL);         if(FALSE==bRes)                 {MessageErrorBox(GetLastError(),L"Read File");}         hClockFont=CreateFontIndirect(&g_pClockNode->logFont); } void Thread_Switch_Pic_Type(HANDLE hFileHandle) {         BOOL bRes;         DWORD        dwReadByte;         g_PlayNode.nType=PIC_Type;         if(g_PlayNode.pPointer)                 free(g_PlayNode.pPointer);         g_PlayNode.pPointer=malloc(sizeof(Arm_Pic_SetInfo));                 if(g_PlayNode.pPointer==NULL)                                 MessageErrorBox(-1,L"Malloc");         bRes=ReadFile(hFileHandle,g_PlayNode.pPointer,sizeof(Arm_Pic_SetInfo),&dwReadByte,NULL);         if(FALSE==bRes)                 {MessageErrorBox(GetLastError(),L"Read File");}         g_PlayNode.PathName=                 (TCHAR *)malloc(((Arm_Pic_SetInfo *)g_PlayNode.pPointer)->nPathLength*sizeof(TCHAR));         if(g_PlayNode.PathName==NULL)                 MessageErrorBox(-1,L"Malloc");         bRes=ReadFile(hFileHandle,g_PlayNode.PathName,sizeof(TCHAR)*((Arm_Pic_SetInfo *)g_PlayNode.pPointer)->nPathLength,                 &dwReadByte,NULL);         if(FALSE==bRes)                 {MessageErrorBox(GetLastError(),L"Read File");}         PlayPic(); } void Thread_Switch_Label_Type(HANDLE hFileHandle,int &nUsedLabelItem) {         Arm_Label_Node *pLabel;         BOOL        bRes;         DWORD        dwReadByte;         if(NULL==g_pLabelNode)         {                 g_pLabelNode=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));                 if(g_pLabelNode==NULL)                         MessageErrorBox(-1,L"Malloc");                         pLabel=g_pLabelNode;                 }else                 {                         pLabel=g_pLabelNode;                         while(NULL!=pLabel->next)                                 pLabel=pLabel->next;                         pLabel->next=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));                         if(g_pLabelNode->next==NULL)                                 MessageErrorBox(-1,L"Malloc");                         pLabel=pLabel->next;                 }         pLabel->next=NULL;         pLabel->pArm_Label_SetInfo=(Arm_Label_SetInfo *)                 malloc(sizeof(Arm_Label_SetInfo));         if(pLabel->pArm_Label_SetInfo==NULL)                 MessageErrorBox(-1,L"Malloc");         bRes=ReadFile(hFileHandle,pLabel->pArm_Label_SetInfo,sizeof(Arm_Label_SetInfo),&dwReadByte,NULL);         if(FALSE==bRes)                 {MessageErrorBox(GetLastError(),L"Read File");}         bRes=ReadFile(hFileHandle,pLabel->tContent,sizeof(TCHAR)*pLabel->pArm_Label_SetInfo->nContentLength,&dwReadByte,NULL);         if(FALSE==bRes)                 {MessageErrorBox(GetLastError(),L"Read File");}         hLabelFont[nUsedLabelItem++]=CreateFontIndirect(&pLabel->pArm_Label_SetInfo->logFont); } void Thread_Switch_NewNode(int &nUsedLabelItem) {         BOOL bRes;         Arm_Label_Node *pLabel;         nUsedLabelItem=0;         for(int i=0;inext;                 free(g_pLabelNode->pArm_Label_SetInfo);                 free(g_pLabelNode);                 g_pLabelNode=pLabel;         }         if(NULL!=g_pClockNode)                 free(g_pClockNode);                 g_pClockNode=NULL;                 g_pLabelNode=NULL; } void PlayPic() {         CIImage mage;         CString strPath;         strPath=PicPathExtent;         strPath+=g_PlayNode.PathName;         mage.Draw(g_hIImageDC,0,0,g_nScreenWidth,g_nScreenHeight,strPath);         int i=0;         while(1)         {                 BitBlt(g_hMiddleDC,0,0,i,g_nScreenHeight,g_hIImageDC,g_nScreenWidth-i,0,SRCCOPY);                 SendMessage(g_hWnd,MSG_COPYSCREEN,0,0[color=#FF0000]);//这里用SendMessage,不用                                                                 //PostMessage,来解决                                                                //一个时刻只有一个地方对HDC进行操作.(个人认                                                              //为可以,如果有不妥请指出)[/color]                 Sleep(5);                 i++;                 if(i>=g_nScreenWidth)                         break;         } } LRESULT CLED_PlayerDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {         // TODO: Add your specialized code here and/or call the base class         switch(message)         {         case MSG_COPYSCREEN:                 msg_CopyScreen();                 break;         }         return CDialog::WindowProc(message, wParam, lParam); } void CLED_PlayerDlg::msg_CopyScreen() {         Arm_Label_Node *pLabel;         HDC hdc=::GetDC(this->m_hWnd);[color=#FF0000]//注意:这里我是用API函数做的, 如果我用MFC 做                                            //CDC *dc=this->GetDC();dc->BitBlt(...);ReleaseDC(dc);                                       //的话 会有内存泄露不知道为什么,请指教[/color]         BitBlt(g_hTopDC,0,0,g_nScreenWidth,g_nScreenHeight,g_hMiddleDC,0,0,SRCCOPY);         pLabel=g_pLabelNode;         int nItem=0;         while(NULL!=pLabel)         {                 DrawLabel(pLabel,nItem++);                                        pLabel=pLabel->next;         }         if(NULL!=g_pClockNode)                 DrawClock(g_pClockNode);         BitBlt(hdc,0,0,g_nScreenWidth,g_nScreenHeight,g_hTopDC,0,0,SRCCOPY);         ::ReleaseDC(this->m_hWnd,hdc);         }复制代码 程序可以说是顺序执行的了.....但我以后还要添加别的消息响应,所以还是把读文件放到了一个单独的线程里面.  详情 回复 发表于 2008-3-4 09:35
点赞 关注

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
DWORD   WINAPI   Thread_ReadPlayList(LPVOID   lpParam)
中的问题:
1、打开文件后,在每个退出点都不关闭。
2、switch(nTemp) 中都不处理 default
3、不检查指针是否有值就直接分配。g_pClockNode=(Arm_Clock_SetInfo   *)malloc(sizeof(Arm_Clock_SetInfo))
不要认为你的文件都按照你认为的方式排列,只要有一点顺序问题,你的程序就会crash.
4、居然还有goto, 看得很晕。

建议加入log,然后出问题后看log 就行了
 
 

回复

94

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
楼上说的好, 那些fopen之类的函数一定要fclose,有配对函数的调用一定要注意。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

4
 
最好是自己加入调试语句,看看问题可能出现在什么地主
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
重贴一下代码吧,格式都丢了。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

6
 
哎,格式乱啊!
fread的时候最好一次读完,然后fclose掉。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

7
 
TO billy14
你说一次读完整个文件???我这个文件大小不知道呀,也许文件很大呢,所以我才一个节目单元的读,不然,如果文件很大,会把内存都用光的,我一次读一个单元的目的 就是省内存.
TO jennyvenus
你说格式丢了??什么格式?
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

8
 
俺是说,代码的缩进格式,你应该加上c风格

比如

[code]

就比
int i = 0;

好看。
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

9
 
你的文件存储应该是有固定的格式的吧,一次读完再去内存中取数这样程序的运行会快些。我之前读过一个10M的文件,发现一次读完,比要用的时候读程序快很多,当然这只是个人意见!
他说格式丢了,是说你的代码都左对齐了。
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

10
 
啊,理解错了,呵呵!
当然你要是只用到文件的一小部分信息还是一点一点的读好!
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

11
 
帮楼主重新贴一下代码,
这样大家好看点。哈哈。今天很无聊的说。


  1. DWORD WINAPI Thread_ReadPlayList(LPVOID lpParam)
  2. {
  3.         FILE * f;
  4.         f=_wfopen(PlayListPath,L"rb");
  5.         if(NULL==f)
  6.         {
  7.                 //传送错误信息:文件打开失败
  8.                 MessageBoxW(NULL,L"Open file false",L"",MB_OK);
  9.                 return 1;
  10.         }
  11.         int nWidth,nHeight;
  12.         int nTemp,nUsedLabelItem;
  13.         Arm_Label_Node *pLabel;
  14.         fread(&nWidth,1,sizeof(int),f);
  15.         fread(&nHeight,1,sizeof(int),f);
  16.         if(nWidth!=g_nScreenWidth ? ?nHeight!=g_nScreenHeight)
  17.         {
  18.                 //传送错误信息:节目列表错误,不是当前屏幕的节目列表
  19.                 MessageBoxW(NULL,L"width && Heiht false",L"",MB_OK);
  20.                 return 1;
  21.         }
  22.         while(!g_bStop)
  23.         {//{{{
  24.                 while(0!=g_PlayNode.nType)//非空结点
  25.                 {
  26.                         Sleep(1);
  27.                 }
  28.                 WaitForSingleObject(hMutexNode,INFINITE);
  29. READNEXTINFO:
  30.                 fread(&nTemp,1,sizeof(int),f);

  31.                 CString str;
  32.                 str.Format(L"nTemp=%d",nTemp);

  33.                 if(feof(f))
  34.                 {
  35.                         fseek(f,8,SEEK_SET);
  36.                         goto READNEXTINFO;
  37.                 }
  38.                 switch(nTemp)
  39.                 {
  40.                 case CLOCK_Type:
  41.                         g_pClockNode=(Arm_Clock_SetInfo *)malloc(sizeof(Arm_Clock_SetInfo));
  42.                         fread(g_pClockNode,1,sizeof(Arm_Clock_SetInfo),f);
  43.                         hClockFont=CreateFontIndirect(&g_pClockNode-> logFont);
  44.                         break;
  45.                 case PIC_Type:
  46.                         g_PlayNode.nType=PIC_Type;
  47.                         g_PlayNode.pPointer=malloc(sizeof(Arm_Pic_SetInfo));
  48.                         fread(g_PlayNode.pPointer,1,sizeof(Arm_Pic_SetInfo),f);
  49.                         g_PlayNode.PathName=
  50.                                 (TCHAR *)malloc(((Arm_Pic_SetInfo *)g_PlayNode.pPointer)-> nPathLength*sizeof(TCHAR));
  51.                         fread(g_PlayNode.PathName,
  52.                                 ((Arm_Pic_SetInfo *)g_PlayNode.pPointer)-> nPathLength,
  53.                                 sizeof(TCHAR),f);
  54.                         break;
  55.                 case LABEL_Type:

  56.                         if(NULL==g_pLabelNode)
  57.                         {
  58.                                 g_pLabelNode=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));
  59.                                 pLabel=g_pLabelNode;
  60.                         }else
  61.                         {
  62.                                 pLabel=g_pLabelNode;
  63.                                 while(NULL!=pLabel-> next)
  64.                                         pLabel=pLabel-> next;
  65.                                 pLabel-> next=(Arm_Label_Node *)malloc(sizeof(Arm_Label_Node));
  66.                                 pLabel=pLabel-> next;
  67.                         }
  68.                         pLabel-> next=NULL;
  69.                         pLabel-> pArm_Label_SetInfo=(Arm_Label_SetInfo *)
  70.                                 malloc(sizeof(Arm_Label_SetInfo));
  71.                         fread(pLabel-> pArm_Label_SetInfo,1,sizeof(Arm_Label_SetInfo),f);
  72.                         fread(pLabel-> tContent,pLabel-> pArm_Label_SetInfo-> nContentLength,sizeof(TCHAR),f);
  73.                         hLabelFont[nUsedLabelItem++]=CreateFontIndirect(&pLabel-> pArm_Label_SetInfo-> logFont);
  74.                         goto READNEXTINFO;
  75.                         break;
  76.                 case NEWNODE:
  77.                         if(1)
  78.                         {
  79.                                 nUsedLabelItem=0;
  80.                                 for(int i=0;i
  81.                                 {
  82.                                         if(NULL!=hLabelFont[i])
  83.                                         {
  84.                                                 int nRes=DeleteObject(hLabelFont[i]);
  85.                                                 hLabelFont[i]=NULL;
  86.                                                 if(0==nRes)
  87.                                                         MessageBoxW(NULL,L"DeleteObject hLabelFont",L"ERROR",MB_OK);
  88.                                         }
  89.                                 }
  90.                                 if(NULL!=hClockFont)
  91.                                 {
  92.                                         int nRes=DeleteObject(hClockFont);
  93.                                         hClockFont=NULL;
  94.                                         if(0==nRes)
  95.                                                 MessageBoxW(NULL,L"DeleteObject hClockFont",L"Error",MB_OK);
  96.                                 }
  97.                         }
  98.                         while(NULL!=g_pLabelNode)
  99.                         {
  100.                                 pLabel=g_pLabelNode-> next;
  101.                                 free(g_pLabelNode-> pArm_Label_SetInfo);
  102.                                 free(g_pLabelNode);
  103.                                 g_pLabelNode=pLabel;
  104.                         }
  105.                         if(NULL!=g_pClockNode)
  106.                                 free(g_pClockNode);
  107.                         g_pClockNode=NULL;
  108.                         g_pLabelNode=NULL;
  109.                 case ENDNODE:
  110.                         // MessageBoxW(NULL,L"EndNode",L"ReadPlayList",MB_OK);
  111.                         goto READNEXTINFO;
  112.                         break;
  113.                 }
  114.                 ReleaseMutex(hMutexNode);
  115.         }//}}}
  116.         //检查未释放资源,进行释放
  117.         return 1;
  118. }

  119. DWORD WINAPI Thread_Play(LPVOID lpParam)
  120. {
  121.         HDC hdc=::GetDC(g_hWnd);
  122.         HANDLE handle;
  123.         Arm_Label_Node *pLabel;
  124.         while(!g_bStop)
  125.         {//{{{
  126.                 while(0==g_PlayNode.nType)
  127.                 {
  128.                         Sleep(1);
  129.                 }
  130.                 WaitForSingleObject(hMutexNode,INFINITE);
  131.                 switch(g_PlayNode.nType)
  132.                 {
  133.                 case PIC_Type:
  134.                         g_bThreadStop=FALSE;
  135.                         //启动一个图片线程
  136.                         handle=CreateThread(NULL,0,Thread_PlayPic,NULL,0,NULL);
  137.                         CloseHandle(handle);
  138.                         break;
  139.                 }
  140.                 while(!g_bStop&&!g_bThreadStop)
  141.                 {
  142.                         BitBlt(g_hTopDC,0,0,g_nScreenWidth,g_nScreenHeight,g_hMiddleDC,0,0,SRCCOPY);
  143.                         pLabel=g_pLabelNode;
  144.                         int nItem=0;
  145.                         while(NULL!=pLabel)
  146.                         {
  147.                                 DrawLabel(pLabel,nItem++);
  148.                                 pLabel=pLabel-> next;
  149.                         }
  150.                         if(NULL!=g_pClockNode)
  151.                                 DrawClock(g_pClockNode);
  152.                         BitBlt(hdc,0,0,g_nScreenWidth,g_nScreenHeight,g_hTopDC,0,0,SRCCOPY);
  153.                         Sleep(5);
  154.                 }
  155.                 g_PlayNode.nType=0;
  156.                 free(g_PlayNode.pPointer);
  157.                 free(g_PlayNode.PathName);
  158.                 ReleaseMutex(hMutexNode);
  159.         }//}}}
  160.         return 1;
  161. }

  162. DWORD WINAPI Thread_PlayPic(LPVOID lpParam)
  163. {
  164.         CIImage mage;
  165.         CString strPath;
  166.         strPath=PicPathExtent;
  167.         strPath+=g_PlayNode.PathName;
  168.         mage.Open(strPath);
  169.         mage.Draw(g_hIImageDC,0,0,g_nScreenWidth,g_nScreenHeight,0);
  170.         int i=0;
  171.         while(1)
  172.         {
  173.                 BitBlt(g_hMiddleDC,0,0,i,g_nScreenHeight,g_hIImageDC,g_nScreenWidth-i,0,SRCCOPY);
  174.                 Sleep(5);
  175.                 i++;
  176.                 if(i> =g_nScreenWidth)
  177.                         break;
  178.         }
  179.         g_bThreadStop=TRUE;
  180.         return 1;
  181. }
复制代码
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

12
 
有疑问:
g_hIImageDC是个全局变量,不知是否会被多个线程用到呢?还是只有线程Thread_PlayPic?
从你给的代码中看不出来。
但就算是只有Thread_PlayPic用,由于Thread_Play会也可能会启动多个Thread_Play线程.
我记得MS的文档里提到过,不可以多个线程同时对一个HDC就行操作,否则会引起死锁。
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

13
 
“由于Thread_Play会也可能会启动多个Thread_Play线程”
打错了,应当是
"由于Thread_Play会也可能会启动多个Thread_PlayPic线程"
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

14
 
如果真是这个原因,
既使g_hIImageDC改成局部变量也无法避免这个死锁,因为多调几次GetDC()无济于事,还是同一个GDC Object.

最好是永远只启动一个Thread_PlayPic,所有对g_hIImageDC的操作都以PostThreadMessage的方式给它一个人去做。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

15
 
To:chengchenz
Thread_PlayPic代码如下,如果仔细看我代码 就会发现,同时最多只会启动一个Thread_PlayPic的.但你说MS文档提示不让多个线程对一个HDC进行操作.可是 我现在程序就必须这么做呀.一个Thread_PlayPic里对g_hMiddleDC进行不停绘图,而Thread_Play现成在把这个HDC拷贝到另一个HDC上,不然如何做图片特效呀????
还有就是,我一开始也是怕多个线程访问一个HDC会出现问题.所以换了一个全局的BITMAP对象 在每个线程里面在CreateCompatibleDC,在让这个新HDC选择这个BITMAP对象,但是 后来发现问题,一查 MSDN上面提示一个HBITMAP不能SelectObject进多个HDC,不然除第一个HDC外,其他的HDC是得不到图片的。所以我才弄的全局的HDC
  1. DWORD WINAPI Thread_PlayPic(LPVOID lpParam)
  2. {
  3.         CIImage mage;
  4.         CString strPath;
  5.         strPath=PicPathExtent;
  6.         strPath+=g_PlayNode.PathName;
  7.         mage.Open(strPath);
  8.         mage.Draw(g_hIImageDC,0,0,g_nScreenWidth,g_nScreenHeight,0);
  9.         int i=0;
  10.         while(1)
  11.         {
  12.                 BitBlt(g_hMiddleDC,0,0,i,g_nScreenHeight,g_hIImageDC,g_nScreenWidth-i,0,SRCCOPY);
  13.                 Sleep(5);
  14.                 i++;
  15.                 if(i>=g_nScreenWidth)
  16.                         break;
  17.         }
  18.         g_bThreadStop=TRUE;       
  19.         return 1;
  20. }
复制代码
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

16
 
的确只会有一个Thread_PlayPic;
但是有一点没看明白,你是如何保证g_hMiddleDC被Thread_Play, Thread_PlayPic同时访问时的?
从你的代码上看到,你似乎有一种假设:每5秒钟总是Thread_PlayPic在g_hMiddleDC上先画完,然后Thread_Play再用它.
但这种假设从你现在代码看并不一定成立,虽然在大多数时候确实是这样.
另外,一般窗体都是由主线程创建的(因为一般while(GetMessage())都在主线程里面);所以你的Thread_Play可能还各主线程WM_PAINT存在共用g_hWnd DC冲突的情况.
最好是一个线程只提供数据绘图线程,绘图线程只管绘图.
平时一般都是主线程管UI(包括消息处理和绘图)---用户界面线程,
子线程管监控---工作者线程.
当子线程有数据要重重绘时,SendMessage自定义的消息给窗体,在UI线程里去画.
Thread_Play和Thread_PlayPic很容易并在一起的.而且并一起后也很容易并到主线程(UI线程)里去的(可以在主线程中用SetTimer来定时动画).这样所有的DC访问都只出现在主线程(UI线程)里,不存在任何冲突,也不需要全局DC变量了.
可不可以用以下型式来实现?
窗体消息处理函数:
  1. wndProc()
  2. {
  3.     switch(msg)
  4.     {
  5.     case WM_PAINT:
  6.         BeginPaint();
  7.         drawMidDCtoPaintDC();
  8.         EndPaint();
  9.         break;
  10.     case WM_MYANIMAL:
  11.         i=0;
  12.         settimer(5000);
  13.         break;
  14.     case WM_TIMER:
  15.         drawPicToMidDC();//此函数里包括原来在Thread_Play和Thread_PlayPic的所有终图功能.不要在里面创建线程了.
  16.         i++;
  17.         if(i>=ScreenWidth)
  18.             KillTimer();
  19.         InvalidateRect(hWnd, NULL, FALSE); //最后一个FALSE可防止画背景引起闪烁.
  20.         break;
  21.     }
  22. }

  23. DWORD WINAPI Thread_Play(LPVOID lpParam)
  24. {
  25.         switch(g_PlayNode.nType)
  26.         {
  27.         case PIC_Type:
  28.         SendMessage(g_hWnd, WM_MYANIMAL,......);
  29.         break;
  30.         }
  31. }
复制代码



另外1楼所述的情况你也得重视.
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

17
 
以上伪码中drawPicToMidDC()是把动画所有要画的东西画到g_hTopDC上.
drawMidDCtoPaintDC()是把g_hTopDC画到Window的PaintDC上.
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

18
 
呵呵,这程序跑起来不死机就奇怪了。chengchenz这几天也确实很无聊。鉴定完毕!
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

19
 
TO chengchenz:
那你伪代码我看了,drawPicToMidDC()是什么?直接顺序执行的?还是里面启动了TIMER???这个代码里面 要不停的绘制图片(要一段时间,不如说5秒,而同时还要把,g_hMiddleDC上的东西 COPY到g_hTopDC上,在再窗体上显示出来.不然给人的感觉图片不是动的呀.)你那里没也看到对g_hMiddleDC的同时操作时候的保护....我这里也没想明白,所以 就根本没有保护,而且如果加上互斥量的话,可能会使图片看起来一卡一卡的,所以最好是一个就是负责动画,另一个负责COPY...

小弟,就只能想到这方法了.如果您有更好的方法告诉一声.对于你说的所有操作都放到主程序里面.我会试下的.等我试完在把结果告诉大家
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

20
 
TO nbcool:
看来你看出我这个哪里有问题了.麻烦告诉声.我这里都急坏了 谢谢
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表