美文网首页
c++ 主线程,子线程 冲突的解决方案

c++ 主线程,子线程 冲突的解决方案

作者: 古典小说 | 来源:发表于2017-11-23 19:47 被阅读0次

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

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

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

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

因为要绘制涂鸦,所以

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

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

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

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

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

原因:

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

主线程绘制涂鸦,

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

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

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

解决:

1 初始化信号

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

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

2

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

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

DrawScrawl(UINT nFlags, CPoint nPoint){

//涂鸦

ResetEvent(m_hDrawScrawl);//设置为无信号

Draw()//绘制涂鸦过程。。。。。

//。。。。。

SetEvent(m_hDrawScrawl);

}

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

ResetEvent(m_hDrawScrawl);//设置为无信号

dcMem.TransparentBlt(0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), &dcTuyaMem, 0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), RGB(255, 255, 255));

if (m_bTuya&&m_nShapeStyle == 1){

dcMem.TransparentBlt(0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), &dcTuyaMem_Sec, 0, 0, m_rcbmMem.Width(), m_rcbmMem.Height(), RGB(255, 255, 255));

}

SetEvent(m_hDrawScrawl);//设置为有信号

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

WaitForSingleObject(m_hDrawScrawl, 4000);

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();

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

子线程: 

WaitForSingleObject(m_hDrawxml, INFINITE);

ResetEvent(m_hDrawxml);

DrawGifOnDC(memDC, i);

SetEvent(m_hDrawxml);

主线程

WaitForSingleObject(m_hDrawxml, INFINITE);

ResetEvent(m_hDrawxml);

DrawXml();

SetEvent(m_hDrawxml);

相关文章

  • c++ 主线程,子线程 冲突的解决方案

    问题描述, 我开发的任性动图软件,曾经遇到过这样的问题: 任性动图有一个功能是涂鸦功能,就是将你的涂鸦过程生成动...

  • 前端JS进阶六(异步)

    单线程 单线程:只有一个线程,只能做一件事情 原因:避免DOM渲染的冲突 解决方案:异步 避免DOM渲染冲突 浏览...

  • C++主线程调用Java方法

    1. C++ 全局调用Java方法 1.1 C++主线程调用Java方法 在 Android C++多线程-创建子...

  • C++ 线程类thread

    c++ 线程类 thread 注:join 是线程等待,等待子线程结束后在继续执行;线程等待要用sleep_for...

  • 关于线程安全问题

    一、 通过线程池创建A,B,C三个子线程,并设置A子线程执行1秒;B子线程执行3秒; C子线程执行7秒。要求:①主...

  • IOS 面试UI题解

    一、UITableView数据源同步解决方案 并发访问、数据拷贝:当主线程的数据拷贝给子线程后(子线程做了一系列的...

  • GCD延时

    在主线程中延迟执行某动作,不会卡主主线程,不影响后面的东做执行 在子线程中执行某动作,不会卡主整个线程

  • C++ 多线程

    C++ 多线程 | 菜鸟教程 C++ 11 多线程--线程管理 - Brook_icv - 博客园

  • 【Java学习笔记】实战——网络象棋

    源码 1、服务端:主函数 2、服务端:主线程 3、服务端:子线程 4、客户端:主函数 5、客户端:子线程 6、象棋...

  • iOS中点击UITableViewcell弹出UIALertCo

    延迟是因为UIAlertController的操作是在子线程中的解决方案1:把他放到主线程中 解决方案2:点击ce...

网友评论

      本文标题:c++ 主线程,子线程 冲突的解决方案

      本文链接:https://www.haomeiwen.com/subject/lfltbxtx.html