易语言顺序执行速度和线程执行速度的问题
.版本2.支持库EThread.支持库spec.程序集窗口程序集1.程序集变量s,整数型.子程序__启动窗口_创建完毕.局部变量i,整数型.局部变量线程id,整数型.计次...
.版本 2
.支持库 EThread
.支持库 spec
.程序集 窗口程序集1
.程序集变量 s, 整数型
.子程序 __启动窗口_创建完毕
.局部变量 i, 整数型
.局部变量 线程id, 整数型
.计次循环首 (10, i)
启动线程 (&开始, , 线程id)
调试输出 (i)
.计次循环尾 ()
.子程序 开始
调试输出 (“线程” + 到文本 (s))
s = s + 1
为什么此时线程输出的顺序很乱?如果把s=s+1提到调试输出上面就好些,这是为什么? 展开
.支持库 EThread
.支持库 spec
.程序集 窗口程序集1
.程序集变量 s, 整数型
.子程序 __启动窗口_创建完毕
.局部变量 i, 整数型
.局部变量 线程id, 整数型
.计次循环首 (10, i)
启动线程 (&开始, , 线程id)
调试输出 (i)
.计次循环尾 ()
.子程序 开始
调试输出 (“线程” + 到文本 (s))
s = s + 1
为什么此时线程输出的顺序很乱?如果把s=s+1提到调试输出上面就好些,这是为什么? 展开
1个回答
展开全部
因为CPU是轮询执行线程的
虽然现在CPU已经往多核方向发展了,但是线程依然是高于CPU线程数的
比如说我有10条线程要同时执行,但是CPU只有2个核心,那么我不能说2条线程执行完再继续剩下的线程,这样线程就不是同时执行了,线程的意义也就没有了。
所以操作系统一般会为线程分配时间,比如说给A线程10个cpu时间,然后暂停A线程,切换到B线程,再给10个cpu时间,以此类推,造成一种看起来同时运行的效果
你的问题就是这样,因为调试输出速度实际上很慢(你可以计次循环调试输出1000,和不输出1000比比速度),在有限分配的时间里不能完成线程的执行就被切换执行其他线程,最后输出顺序看起来就是乱的甚至和预期结果完全不同,也就是所谓的线程冲突(你的多个线程公用了变量s,但是线程并不安全(不能保证s同一时间只能被一条线程访问),可能导致s最后结果不是10)
虽然现在CPU已经往多核方向发展了,但是线程依然是高于CPU线程数的
比如说我有10条线程要同时执行,但是CPU只有2个核心,那么我不能说2条线程执行完再继续剩下的线程,这样线程就不是同时执行了,线程的意义也就没有了。
所以操作系统一般会为线程分配时间,比如说给A线程10个cpu时间,然后暂停A线程,切换到B线程,再给10个cpu时间,以此类推,造成一种看起来同时运行的效果
你的问题就是这样,因为调试输出速度实际上很慢(你可以计次循环调试输出1000,和不输出1000比比速度),在有限分配的时间里不能完成线程的执行就被切换执行其他线程,最后输出顺序看起来就是乱的甚至和预期结果完全不同,也就是所谓的线程冲突(你的多个线程公用了变量s,但是线程并不安全(不能保证s同一时间只能被一条线程访问),可能导致s最后结果不是10)
追问
谢谢,大体意思能明白,但是为什么s=s+1放在前面就可以了,是因为影响效率的是调试输出?
追答
输出的值并不是s的实际值。你调试输出是这样的 调试输出(到文本(s)),也就是说执行的时候分成了两段代码 tmp=到文本(s) 调试输出(tmp)。那么如果运行完 到文本(s)后线程就被切换了会怎样呢?可能其他线程已经改写了s的值了,但是输出的还是之前的值。
如果调试输出在前,这个问题会很严重,因为调试输出太慢了,很容易被切换
如果调试输出在后,调试输出依然会被切换,但是s=s+1执行很快(只有1条cpu指令),就算在到文本(s)执行后被切换,输出的依然是你期望的数值(每次递增1,不重复),也就是看似顺序的输出内容
你可以在 s=s+1和 调试输出(到文本(s))的中间加一条 延时(1),当程序遇到延时的时候系统会把线程执行切换到其他线程,因为需要延时的线程不需要CPU时间...这样来强行使得线程切换,你会发现输出依然和预期不同
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询