还有玩家会疑惑,这么多tick就不能拆分成多个线程或多个进程分别运算吗?
这又要深入到编程开发上的概念了。
首先线程各自进行运算的时候,最大的难度在于要保证内存安全性。
什么是内存安全性?实际上就是内存中变量数值的修改冲突问题。
第一种情形:冲突。
拿上面工作的例子打个比方。
加入有两个建造任务都需要用到原木,分别让小人A和B各自完成,恰好他们要拿的是同一个原木,该给谁?
单线程:简单,要么A拿要么B拿,另一个人再分配其他的原木。
多线程:A和B拿同一个原木怎么处理?
如果不做处理,那么其中一个人拿了,实际没拿到,程序报错。
如果做处理,把这个原木标记给A,B再换另一个原木。
这再多线程编程中叫做“锁”,这时候多线程并没有提升运行效率,反而因为多个线程间的锁导致额外的开销降低了效率。反映到CPU就是,连个CPU轮流吃满,但不能同时吃满。
反而还不如单线程。
同理,假如一个人要收获一颗作物,这颗作物同时还要计算成熟度,也会造成数值修改上的冲突。
第二种情形:不冲突。
如果两个事物的变化如果完全没关系呢?
似乎可以,但怎么判断两个食物可以各自独立运行?程序员表示头秃。
第三种情形:避开冲突。
既然这涉及到冲突,拿我把内存里的所有变量都给各个线程复制一份各自运算,算完了再合并回来处理行不行?
似乎也可以。但首先要明白两点,内存是的,通常情况变量的复制比变量的修改要更加耗时。
程序的内存占用中,绝大部分是变量的占用。
内存里巨量的变量复制后使用、使用后丢弃对应的是内存的申请使用和释放。
系统剩余的内存还够不够用?不够用还进行复制、申请使用,轻则程序崩溃,重则系统蓝屏。
变量丢弃和内存的回收也需要耗时,同时程序是人写的,人就会犯错,忘了回收,内存申请了不释放,而未释放的内存是不能再利用的,造成的后果一样。
这就是内存泄漏,内存占用无限增长——BOOM。
这又要深入到编程开发上的概念了。
首先线程各自进行运算的时候,最大的难度在于要保证内存安全性。
什么是内存安全性?实际上就是内存中变量数值的修改冲突问题。
第一种情形:冲突。
拿上面工作的例子打个比方。
加入有两个建造任务都需要用到原木,分别让小人A和B各自完成,恰好他们要拿的是同一个原木,该给谁?
单线程:简单,要么A拿要么B拿,另一个人再分配其他的原木。
多线程:A和B拿同一个原木怎么处理?
如果不做处理,那么其中一个人拿了,实际没拿到,程序报错。
如果做处理,把这个原木标记给A,B再换另一个原木。
这再多线程编程中叫做“锁”,这时候多线程并没有提升运行效率,反而因为多个线程间的锁导致额外的开销降低了效率。反映到CPU就是,连个CPU轮流吃满,但不能同时吃满。
反而还不如单线程。
同理,假如一个人要收获一颗作物,这颗作物同时还要计算成熟度,也会造成数值修改上的冲突。
第二种情形:不冲突。
如果两个事物的变化如果完全没关系呢?
似乎可以,但怎么判断两个食物可以各自独立运行?程序员表示头秃。
第三种情形:避开冲突。
既然这涉及到冲突,拿我把内存里的所有变量都给各个线程复制一份各自运算,算完了再合并回来处理行不行?
似乎也可以。但首先要明白两点,内存是的,通常情况变量的复制比变量的修改要更加耗时。
程序的内存占用中,绝大部分是变量的占用。
内存里巨量的变量复制后使用、使用后丢弃对应的是内存的申请使用和释放。
系统剩余的内存还够不够用?不够用还进行复制、申请使用,轻则程序崩溃,重则系统蓝屏。
变量丢弃和内存的回收也需要耗时,同时程序是人写的,人就会犯错,忘了回收,内存申请了不释放,而未释放的内存是不能再利用的,造成的后果一样。
这就是内存泄漏,内存占用无限增长——BOOM。