进程和线程的理解
线程是操作系统能够进行预算调度的最小单位,它包含在进程中是进程中的实际运作单位。
Linux 进程有父进程和子进程,window 系统的进程是平等关系
一个标准的线程有线程 ID ,当前指令指针,寄存器集合和堆栈组成,在许多系统中,创建一个线程比创建一个进程要快 1- 100 倍。
每一个进程都认为自己独占所有的计算器硬件资源
进程就是独立的王国,进程间不可以随便共享数据
线程就是省份,同一个进程内的线程可以共享进程的资源,每一个进程拥有自己独立的堆栈。
Python 中的进程和线程
进程会启动一个解释器进程,线程共享一个解释器进程。
线程
创建一个最简单的线程程序
import threading def worker(): print("hello world") t = threading.Thread(target=worker) # 创建线程对象 t.start() #启动
使用 print 函数打印(因为线程切换回打断 print 函数的执行 )会导致线程不安全,推荐使用 logging
import logging import threading FORMAT = '%(asctime-15s\t [%(threadName)s, %(thread)8d] %(message)s)' logging.basicConfig(level=logging.INFO, format=FORMAT) def worker(): for i in range(100): logging.info("{} is running".format(threading.current_thread().name)) for i in range(5): name = "workr-{}".format(i) threading.Thread(target=worker).start()
线程安全:线程执行一段代码,不会产生不确定的结果,那这段代码就是线程安全的
daemon 线程和 no-daemon 线程
这里的 daemon 不是 linux 中的守护进程
如果有 non-daemon 线程的时候,主线程退出时也不会杀掉所有daemon线程,直到所有 non-daemon 线程全部结束,如果还有 daemon 线程,主线程需要退出,会结束所有的 daemon 线程退出
threading.local
Python 提供 threading.local 类,将这个类实例化得到一个全局对象,但是不同线程使用这个对象存储的数据其他线程看不见。
ctx = threading.local() ctx.x = 123
Threading.local 类构建了一个大字典,其元素是每一线程实例的地址为 key 和线程对象引用线程单独的字典的映射
{id(Thread)->(ref(Thread),thread-local dict)}
通过 threading.local 实例就可以在不同的线程中,安全的使用线程独有的数据,做到线程间数据隔离,如同本地变量一样安全。
threading.Timer
Threading.Timer 继承自 Thread,这个类用来定义多久执行一个函数
class threading.Timer(interval, function, args=None, kwargs=None)
Start 方法执行之后,Timer 对象会处于等待状态,等待了 interval 之后,开始执行 function 函数的
如果在执行函数之前的等待期间使用了 cancle 方法就会跳过执行函数结束。
def worker(): print("hello world") t = threading.Timer(5,worker)