当前位置:   article > 正文

主线程,子线程资源冲突,解决方案_子线程 调用eigen pardiso 访问冲突

子线程 调用eigen pardiso 访问冲突


问题描述,  我开发的任性动图软件,曾经遇到过这样的问题:


     任性动图有一个功能是涂鸦功能,就是将你的涂鸦过程生成动图,怎么实现的呢?

     有一个主显示内存,用以显示界面图像

     有一个辅显示内存,用以生成动图时,绘制动图


     因为要绘制涂鸦,所以

     开辟了一个涂鸦内存,将涂鸦绘制在这个内存上,然后再分别拷贝到主次内存上。


 因为要生成动图,而且生成的过程中,要适时涂鸦,所以启用线程的方式。   


     开辟了一个线程,这个线程负责将涂鸦过程,生成GIF动图

     主线程复杂绘制涂鸦,然后将绘制好的涂鸦内存,拷贝到显示内存上。


问题来了:生成的GIF动图,发现很多时候,某一帧是空白的,也就是说,那一帧 并没有将涂鸦绘制到动图上。


原因:

        后来经分析,原因很可能是这儿产生了冲突 。

         

        主线程绘制涂鸦,

        主线程将涂鸦内存拷贝到主内存上

        子线程将涂鸦内存拷贝到辅内存上


        这时就有可能产生冲突了: 主线程在绘制涂鸦内存的时候,正好遇到子线程想将涂鸦内存拷贝到辅内存上,也就是主线程和子线程同时操作涂鸦内存,这样就产生矛盾了,由此引发了这个问题。


解决:

        

1 初始化信号

HANDLE m_hDrawScrawl ; //自动复原 有信号  保证生成动图过程中 绘制的完整性  

    

m_hDrawScrawl = CreateEvent(NULL, TRUE, TRUE, NULL);  //


主线程中,涂鸦内存处理过程,设置为无信号


绘制涂鸦函数中,绘制过程中,设置为无信号,绘制结束后,再置位有信号。

  1. DrawScrawl(UINT nFlags, CPoint nPoint){
  2. //涂鸦
  3. ResetEvent(m_hDrawScrawl);//设置为无信号
  4. Draw()//绘制涂鸦过程。。。。。
  5. //。。。。。
  6. SetEvent(m_hDrawScrawl);
  7. }


主线程涂鸦拷贝过程设置为无信号

  1. ResetEvent(m_hDrawScrawl);//设置为无信号
  2. dcMem.TransparentBlt(0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), &dcTuyaMem, 0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), RGB(255, 255, 255));
  3. if (m_bTuya&&m_nShapeStyle == 1){
  4. dcMem.TransparentBlt(0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), &dcTuyaMem_Sec, 0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), RGB(255, 255, 255));
  5. }
  6. SetEvent(m_hDrawScrawl);//设置为有信号



3  子线程等待主线程的涂鸦内存操作完毕后,再操作


  1. WaitForSingleObject(m_hDrawScrawl, 4000);
  2. dcMem.TransparentBlt(pMiddleChunk->Left, pMiddleChunk->Top, pMiddleChunk->Width, pMiddleChunk->Height, &dcTuyaMem, pMiddleChunk->Left, pMiddleChunk->Top, pMiddleChunk->Width, pMiddleChunk->Height, RGB(255, 255, 255));


当然,这只考虑了一层,只考虑了子线程处理时,一定要等主线程完毕后才可,没有考虑子线程处理涂鸦内存时,防止主线程也在处理。因为我的子线程只是个拷贝,所以没有双向考虑。


要想主线程、辅线程都不打扰。

可能要试试下面的策略


设置同一个信号量,用这个信号量进行控制,主线程等待子线程完毕后,再进行,子线程等待主线程完毕后,再进行。


hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); 

主线程:


   WaitForSingleObject(hEvent,INFINITE)

   ResetEvent(hEvent)

   .....

   SetEvent(hEvent)


辅线程:


   WaitForSingleObject(hEvent,INFINITE)
   ResetEvent(hEvent)
   .....
   SetEvent(hEvent)


   

比如:

子线程绘图函数  DrawGifOnDC(memDC, i);  

主线程绘图函数 DrawXml();

两者有冲突,可以这么解决


子线程:

  1. WaitForSingleObject(m_hDrawxml, INFINITE);
  2. ResetEvent(m_hDrawxml);
  3. DrawGifOnDC(memDC, i);
  4. SetEvent(m_hDrawxml);

主线程


  1. WaitForSingleObject(m_hDrawxml, INFINITE);
  2. ResetEvent(m_hDrawxml);
  3. DrawXml();
  4. SetEvent(m_hDrawxml);



                    

                   


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号