距离上次笔记才过去几天,一会的时间Windows 11就发布了,确实和泄露版是一样的。个人感觉唯一比较新奇的就是内置了安卓模拟器,除此之外就是UI界面的美术风格调整和商城应用的更新,还有对多核性能的小幅度优化(实在是无伤大雅(滑稽))。
操作系统都有啥(二)
上次吹到了进程的概念,现在该吹线程了。以前想到过一个比喻,自己感觉还挺形象:一个进程就是打开一局英雄联盟,十个线程就相当于游戏里的十个英雄。通过这个例子应该可以理解,线程是属于进程的,一个进程可以有多个线程。
重点来了,多线程的概念超级超级重要,毕竟很少有软件运行全程就一个线程,然后每次只做一件事(除了你做练习题时写的程序)。那么咱就会疑惑,多个线程在同时运行时,程序不会因为线程的运行不同步发生混乱吗?嘿嘿嘿,当然会!所以就需要有线程调度和锁的概念。
首先,给线程的状态进行三个定义,分别是运行,就绪,等待。处于运行中的线程可以在一段被分配的时间内使劲执行,这段时间叫做时间片,当时间片耗尽的时候,若这个线程还有需要运算的内容,这个线程就会进入就绪状态,然后解除对CPU的占用,轮到下一个线程使用CPU。若这个线程在时间片用尽前开始等待某事件,这个线程会进入等待状态,当等待的事件全部运行完,这个线程会进入就绪状态。
除了对CPU资源的调度,多线程还要考虑数据安全,比如:
现在有两个线程,
一个是i=1;i=i+1(就叫它T1吧)
一个是i=i-1(就叫它T2吧)
1.如果在某种情况下,T1运行了一半,T1的寄存器X1存到了AX1=1,
2.这时T1的时间片用完了,切换到T2运行,T2的寄存器存到AX2=1。
3.然后再到T1,该运行i+1了,AX1=i+1=2。
4.再到T2,AX2=i-1,AX2=0
5.到最后,AX1将值赋回给i,i的值变成2了
6.然后AX2也将值赋回给i,i的值变成0了。
还有几种情况,分别会导致最后i的值是0,1,2,出现这种问题是因为运行一条指令的时间不是固定的,在同样的时间片内可能运行不同数量的指令,不过单条指令并不会被中断,我们将不允许被中断的操作称为原子操作,显然单条指令就是原子操作。那么怎么解决这个问题呢?那就是对操作数添加锁,并在访问结束后释放,这个过程称为同步。同步的手段有多种,比如:二元信号量,互斥量,临界区,读写锁,这些方式的目的都是为了保护数据不被多个线程同时使用时紊乱。
文中图片引用自:
《程序员的自我修养》作者:俞甲子,电子工业出版社,2020年11月出版