小春网

 找回密码
 注册账号
查看: 1842|回复: 25
收起左侧

[IT 交流] ~~求助~~关于多线程的问题~~

[复制链接]
发表于 2011-11-30 18:29:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册账号

x
多线程之间同步问题是个很头疼的问题但我遇到的确是在一个线程内顺序的问题

在一个opengl项目中,display loop中,当按某一个按键时,需要另起一个线程,来进行一些大量的计算(计算时间比较长,六台HP station 运算15分钟左右)。。。。
问题是,在新启的这个线程中(假设为threadFunc()),执行以下的工作
threadFunc()
{
    for(i=0~9)
   {
        dealwith(i)
        output_data_2_file(i)
   }
   get_result_from_10_files();
}
源代码上万行,就不贴出来了,这里大致说明一下
dealwith是在3维空间中根据当前空间位置,周围环境作出一系列计算,假设这里要算10次,
计算完后,将通过output_data_2_file数据保存到10个文件中
最后通过get_result_from_10_files来得出结果,并显示出来

问题在于,按说应该是计算完一次,保存一次数据,最后分别读出来,但实际运行结果并非如此,有可能第一组数据还没有算出来,就已经开始第二组,第三组的文件计算了。。。。后一组计算需要依赖前一组计算的结果,因此,最后得到的肯定不对~~~~
windows的多线程确实有一个乱序的问题,但查了很多相关资料没有找到比较好的解决方案,随机性比较大,有时能得到正确结果,有时确得到一个莫名其妙的结果》》》
不知有没有人遇到过类似问题,分享一下~~~
谢谢

评分

参与人数 1 +88 收起 理由
憨吃迷糊睡 + 88 鼓励讨论这样的技术问题

查看全部评分

头像被屏蔽
发表于 2011-11-30 19:04:06 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2011-11-30 19:41:51 | 显示全部楼层
对于windows NT内核服务器来说,每个线程都有一个从0到31的优先级号码。系统优先观察优先级为31的线程,并以循环的方式对他们进行调度。只要优先级为31的线程是可调度的,系统就绝对不会将优先级为0到30的线程分配给cpu。
高优先级线程将抢在低优先级线程之前运行。如果一个优先级为5的线程正在运行,系统发现一个高优先级的线程准备要运行,那么系统就会立刻暂停低优先级县城的运行(即使它处于它的时间片中),并且将cpu分配给高优先级线程。

以上文字出自《Windows 核心编程》by Jeffrey Richter,这只是Windows线程调度算法的两个(通过实验观测到的)特性,并不完整。
而下面这段话则是Microsoft的官方发言:
    Microsoft没有将调度程序的行为特性完全固定下来
    Microsoft没有让应用程序充分利用调度程序的特性
    Microsoft的调度程序的算法是变化的,在编写代码时应该有所准备

评分

参与人数 1 +30 收起 理由
憨吃迷糊睡 + 30 赞一个

查看全部评分

回复

使用道具 举报

发表于 2011-11-30 20:25:15 | 显示全部楼层
这个,其实是最基本的多线程问题,而且你每个线程运行时间那么长,相对还比较好控制,和你做什么计算没有太大关系。

我不太明白你描述的问题,如果后一组计算需要依赖前一组计算的结果,那不是串行么?使用多线程还有意义不?还是说每个线程都有10组数据要算,10个线程同时计算?相互之间需要做什么同步控制?
回复

使用道具 举报

 楼主| 发表于 2011-11-30 20:28:51 | 显示全部楼层
感谢你的回复,优先级其实我这里是用不到的,那是在多个线程调度的时候需要使用的,我现在其实就一个work thread,当然还有一个主线程,问题是这个线程中,并不会按顺序运行,有些函数或方法会花很长时间,但后面的函数不会等到前面运行完了后再执行(同在一个线程中),《win32多线程编程》那本书倒是提到过这个问题,但也并没有给出完美的解决方案。即将出台的c++1x规范里倒是对这个问题进行了改进,但现在硬件环境以及其他运行库要求必须是vs2003编译器,我用vs2010都无法成功编译。
回复

使用道具 举报

 楼主| 发表于 2011-11-30 20:29:07 | 显示全部楼层
荣耀与梦想 发表于 2011-11-30 19:41
对于windows NT内核服务器来说,每个线程都有一个从0到31的优先级号码。系统优先观察优先级为31的线程,并 ...

感谢你的回复,优先级其实我这里是用不到的,那是在多个线程调度的时候需要使用的,我现在其实就一个work thread,当然还有一个主线程,问题是这个线程中,并不会按顺序运行,有些函数或方法会花很长时间,但后面的函数不会等到前面运行完了后再执行(同在一个线程中),《win32多线程编程》那本书倒是提到过这个问题,但也并没有给出完美的解决方案。即将出台的c++1x规范里倒是对这个问题进行了改进,但现在硬件环境以及其他运行库要求必须是vs2003编译器,我用vs2010都无法成功编译。
回复

使用道具 举报

 楼主| 发表于 2011-11-30 20:31:08 | 显示全部楼层
dataotao 发表于 2011-11-30 19:04
dealwith是独立的线程吗?

整个threadFunc()在一个独立线程中运行,里面没有再开子线程~~
回复

使用道具 举报

 楼主| 发表于 2011-11-30 20:38:58 | 显示全部楼层
microyzy 发表于 2011-11-30 20:25
这个,其实是最基本的多线程问题,而且你每个线程运行时间那么长,相对还比较好控制,和你做什么计算没有太 ...

不好意思,可能是我没有描述清楚,我给出的threadFunc()里所有执行绪都是在一个线程中进行的,这个线程是由主线程创建的,也就是说,整个程序运行中只有一个主线程和一个工作线程(threadFunc),其实工作线程中执行的内容是希望并必须串行执行,但为了不影响界面操作,所以放到一个线程中,但现在的问题是,threadFunc中的函数并不是按顺序串行执行的,打个比方,假如dealwith需要运行10分钟,在 get_result_from_10_files函数中弹出一个对话框,那么正常情况下,应该是10分钟后,才弹出对话框,但现在,只要这个线程一启动,对话框立刻弹出,当然,dealwith函数的处理还在继续~~~~这就是现在要解决的顺序问题。
回复

使用道具 举报

 楼主| 发表于 2011-11-30 21:04:20 | 显示全部楼层
本帖最后由 bakerwhy 于 2011-11-30 21:10 编辑

我再补充描述一下问题吧
首先这不是一个线程调度的问题,也不存在同步的问题
举个例子,以下代码,
for(int i=0; i<1000;i++)
{
     //other func with non-output
     printf("i=%d,", i);
}
for(int k=0; k<1000;k++)
{
     //other func with non-output
     printf("k=%d,", k);
}
如果放到main函数中,结果肯定是:
i=0,i=1,i=2,...........i=999,k=0,k=1,.....k=999,

但如果放到一个线程中(同一个线程),我们期待的结果应该也是和上面一样的,
但实际结果是不稳定的,什么情况都有(当然大部分时间还是正常的),比如会出现以下极端的情况
i=0,i=1,k=1,i=3,k=0..............完全不是按顺序来的,有些在后面的反倒先执行了。。。
回复

使用道具 举报

发表于 2011-11-30 22:09:41 | 显示全部楼层
迷糊估计的问题以及考虑的解决办法:

1)在output_data_2_file函数中是否调用了类似于flush这样的函数,把写缓冲区的数据切实地更新到文件当中去

2)能否考虑在文件中追加写入完成的标志位?在get_result_from_10_files函数中判断这个标志位,如果写操作已经完全完成再读取数据

3)9楼的示例确实挺奇怪的,对标准输出流执行类似flush的操作不知道是否能解决掉这种怪现象

回复

使用道具 举报

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

本版积分规则

小春网
常务客服微信
微信订阅号
手机客户端
扫一扫,查看更方便! 快速回复 返回顶部 返回列表