操作系统

操作系统本质是程序,最初没有操作系统,程序只能人工、按序放到计算机上执行。
操作系统通过线程、进程对象,并发技术,可以使多个程序同时执行

线程

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,一个进程可以并发多个线程,每条线程执行不同任务,共享同进程下的内存空间。
线程切换通过上下文进行,互相记录下上一个执行的信息,会有资源的开销。
同进程下的线程与线程之间,没有主次之分,互不影响
Python中使用 threading 与 concurrent.futures.ThreadingPool 操作多线程

多线程

适用于io密集的,不适用于CPU 密集程序。
频繁的使用上下文切换也是要耗费一定的资源,因为单线程在每次切换任务的时候需要保存当前任务的上下文。
主进程在启动之后会启动一个主线程,线程启动了多个子线程,然而启动的子线程是独立的,所以主线程不会等待子线程执行完毕,而是主线程继续往下执行,并行执行。

  1. for i in range(50):
  2. t = threading.Thread(target=princ, args=('t-%s' % (i),))
  3. t.start()

全局解释器锁

这是解释器级别的锁(Cpython里),同一时间,只能一个线程运行,无法利用多核cpu的优势。
加锁是为了 保证不同的线程操作内部共享的数据 的安全性。
在Python1.5,增加了 free threading 补丁 ,实现了 去除gil,并用更细粒度的锁替代gil,但是在单线程情况下,性能降低了40%

Join()

这会阻塞调用这个方法的线程,直到被调用 join() 的线程终结

守护线程

通过t.daemon = True或者调用 t.setDaemon(True) 设置守护进程,在后台运行,无需担心将其关闭的线程,主线程关闭,守护线程也关闭。
主线程会等待非守护线程运行结束才结束。

线程之间数据通信

递归锁(RLOCK/LOCK)

LOCK RLOCK
原始锁 可重入锁
获得锁 acquire() acquire()
释放锁 release() release()
区别 不属于任何线程,可以在一个线程中加锁,另一个线程解锁 只能在当前线程中释放本线程的锁

条件对象

主动休眠,被动唤醒的场景。