多线程设计问题 求大家帮帮忙 给点意见

caozl 2011-11-09 05:49:38

现有设计如下:
一个图形平台,打算用多线程提高效率。
包括一个界面线程, 一个命令线程, 一个指标计算线程等。
底层的数据结构是一个图形容器 ,用来存放很多图形对象。
图形容器有图形容器反应器列表 ,
每个图形有自己的图形反应器列表。
因为觉得一把锁会比较浪费资源,所以想用多把锁,图形容器和每个图形都有一个mutex成员保护自己的成员函数。

问题如下:
1.图形和图形容器之间,多个图形之间访问,在反应器中访问其他资源会造成死锁。有没有解决类似问题的设计模式或算法处理多线程中资源相

互访问而不会死锁?
2.图形容器的某些操作,比如撤销重做,可能一次会操作很多个图形,有没有设计可以一下全锁定?

...全文
123 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
dfasri 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 caozl 的回复:]

引用 12 楼 dfasri 的回复:
图形输出, 是只能够由主线程来做.
但假如图形处理过程比较复杂, 那么大可以用流水线的方式实现并行. 显卡也是这样做的, 程序也可以这样做. 即每个对象, 都按时输入自己的图形, 然后由主线程去读取其输出图形, 画到相应的位置, 只要有任何一个线程重新计算过图形了, 或者图形有改变, 都通过消息通知主线程去拿, 然后去画, 就可以实现不会互锁了. 而且……
[/Quote]

把你编辑的对象合起来作为一个整体, 写入流水线处理就可以了..同一时间, 用户要么是选择一个范围的对象来操作, 要么就是选择一个对象来操作, 用户是不可能同时各自独立, 操作两个单元, 只针对选中的来做操作而已.

虽然我不知道你现在的软件架构是什么, 但要我写一个图形编辑的软件来说, 总体上流程就是: 主线程接收到用户消息以后, 组建要处理的数据, 交由流水线计算并处理, 得到结果后再通知主线程去领取镜像, 然后画上屏幕.

换句说是指: 当用户选择了一个三角形, 然后拖动向右, 那么就把这个选中的三角形 + 拖动距离 作为数据, 流入处理线程, 处理线程访问三角形的对象, 然后加入这些操作后, 得出现在的位置, 然后把现在的位置和三角形对象作为数据, 再流到主线程. 只要把现在的位置这个值是作为当前值, 而不是让主线程去实时读取, 那么就不会发生图形变形之类的问题.

数据总是在处理线程里面独占的. 通过读取输入, 运算后, 把当前值记录下来, 然后复制一次画有关的数据, 给主线程去画. 这样, 你的一整个处理过程都不用担心对象会被锁住, 也不会并发访问. 而处理过程中, 把处理过程归纳一下形成流水线的形式就可以实现快整处理了.
caozl 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sinservice 的回复:]
每个图形都有自己的mutex? 这种设计是注定不会成功的。
[/Quote]
我是认为每个图形是一个资源,每个资源加一个锁进行保护。可能在比较少的情况下,图形之间会发生交互,比如:通过一个图形反应器,把一个图形关联到另一个图形上,移动的时候会一起移动。
想在设计上防止这种操作引起死锁
lijianli9 2011-11-10
  • 打赏
  • 举报
回复
lz其实问题都想到,剩下的就是你的实践了,不建议一个图形一个锁,太耗资源了,至少用户体验会很差。
caozl 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 dfasri 的回复:]
图形输出, 是只能够由主线程来做.
但假如图形处理过程比较复杂, 那么大可以用流水线的方式实现并行. 显卡也是这样做的, 程序也可以这样做. 即每个对象, 都按时输入自己的图形, 然后由主线程去读取其输出图形, 画到相应的位置, 只要有任何一个线程重新计算过图形了, 或者图形有改变, 都通过消息通知主线程去拿, 然后去画, 就可以实现不会互锁了. 而且每个对象都相互独立了. 假如对象很多, 那么……
[/Quote]
我这里并不只是渲染 还有负责编辑功能的命令线程 加锁本身就是想防止这些线程同时处理同一个对象 但是我担心某个线程在锁定一个对象以后又需要访问别的对象 这样一个线程中就可能试图锁多把锁 如果另一个线程也这样做 那会有死锁的隐患。
dfasri 2011-11-10
  • 打赏
  • 举报
回复
图形输出, 是只能够由主线程来做.
但假如图形处理过程比较复杂, 那么大可以用流水线的方式实现并行. 显卡也是这样做的, 程序也可以这样做. 即每个对象, 都按时输入自己的图形, 然后由主线程去读取其输出图形, 画到相应的位置, 只要有任何一个线程重新计算过图形了, 或者图形有改变, 都通过消息通知主线程去拿, 然后去画, 就可以实现不会互锁了. 而且每个对象都相互独立了. 假如对象很多, 那么可以开启一个线程或几个线程, 来对每个对象进行刷新访问, 或者是根据用户操作修改来进行通知运算线程来运算什么对象.
caozl 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 sinservice 的回复:]
引用 8 楼 caozl 的回复:

引用 3 楼 sinservice 的回复:
每个图形都有自己的mutex? 这种设计是注定不会成功的。

我是认为每个图形是一个资源,每个资源加一个锁进行保护。可能在比较少的情况下,图形之间会发生交互,比如:通过一个图形反应器,把一个图形关联到另一个图形上,移动的时候会一起移动。
想在设计上防止这种操作引起死锁


对资源加锁的想法是没有任……
[/Quote]

这个想法是参考OSG的 OSG的每个数据里都会有一个bool值做标志 当一个线程访问的时候 会把这个标志置为
true 别的线程再访问的时候就要等待或者跳过。
只不过OSG的数据之间是不会相互访问的 而我这里不能保证这一点。
「已注销」 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 caozl 的回复:]

引用 3 楼 sinservice 的回复:
每个图形都有自己的mutex? 这种设计是注定不会成功的。

我是认为每个图形是一个资源,每个资源加一个锁进行保护。可能在比较少的情况下,图形之间会发生交互,比如:通过一个图形反应器,把一个图形关联到另一个图形上,移动的时候会一起移动。
想在设计上防止这种操作引起死锁
[/Quote]

对资源加锁的想法是没有任何错误的,但是,并非对所有可以称为“资源”的东西都可以加“MUTEX”。
系统对象是非常昂贵的,而且数量有限的,不能用系统对象提供的锁对程序中的随机大量的单位一对一加锁。
比如,数据库程序,就不可能对“每个行”(支持行锁的数据库)加系统对象的mutex锁,这就需要一些算法来支持,比如像在数据库里用到的“锁算法”。
jiyuhai1988 2011-11-10
  • 打赏
  • 举报
回复
线程多开点
smwhotjay 2011-11-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 chengbar 的回复:]
我建议 线程数量要结合CPU 数量开启
单核的话,多线程是没有优势的
[/Quote]
caozl 2011-11-09
  • 打赏
  • 举报
回复
线程数量的问题不大 主要的问题还是怎么样才能处理好很多资源之间相互访问时引起死锁
sevancheng 2011-11-09
  • 打赏
  • 举报
回复
我建议 线程数量要结合CPU 数量开启
单核的话,多线程是没有优势的
caozl 2011-11-09
  • 打赏
  • 举报
回复
上一个版本中 用的是整个图形数据库一个mutex 可是这样的话 总是只有一个线程能运行 感觉没有真正发挥多线程的效率。 现在我感觉有点迷茫,想问问大家在处理类似问题的时候有什么好的思路或建议
「已注销」 2011-11-09
  • 打赏
  • 举报
回复
每个图形都有自己的mutex? 这种设计是注定不会成功的。
caozl 2011-11-09
  • 打赏
  • 举报
回复
谢谢楼上的回复。我现在的问题不是死锁了以后排查,而是想在设计上防止死锁的出现以及提高效率。
请叫我涛哥0-0 2011-11-09
  • 打赏
  • 举报
回复
1,如果你实力强,用临界区做同步,效率最高,但容易死锁,得自己去排查。
2,如果没有经验,用内核对象(Event Mutex)去同步,效率会低点,不容易出现死锁。

对资源的同步要自己去设计,没有现成的,因为每个人的环境不通。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧