python线程
每个线程都有自己的栈 和cpu寄存器备份 在线程被调度时保存上一个线程的上下文 并load待调度线程的上下,广义上来说上下文包含cpu寄存器备份和线程栈,叫esp ebp好了,寄存器是暂存数据的用来存运算中间结果的,指令在内存中的专门区段 cpu寄存器中的pc寄存器会指向下一条准备指令的地址,是指令的地址,而且也就pc寄存器存了这个地址,cpu会把pc指向的内存区段读入内部的指令缓存后执行
我要执行10-2*(内存中某个值)
cpu是这样走的
首先 会把(内存中某个值)加载到一个寄存器 叫r1吧
然后执行mul命令 将r1和一个立即数相乘 结果存到r2
立即数是什么
最后 执行sub命令 将立即数10和r2相减 存入r3
当然 也可以存回r1或r2
最终 r3被写会内存
cpu不可能把中间结果r2直接写入内存 不写入寄存器
因为这样代价太大
堆栈指针寄存器存的是存储数据的地址
上下文是线程的概念
进程是线程和资源的容器
每个进程都有自己的地址空间 进程间的资源相互独立 一个进程无法直接读写另一进程地址空间中的数据每个进程都有自己的地址空间 进程间的资源相互独立 一个进程无法直接读写另一进程地址空间中的数据,进程只它只是一个容器
所以python处理计算密集型的任务尽量起子进程 不要创建线程,这是为了绕开gil的限制,python有个gil,这玩意很多脚本语言都有 是很难绕过的硬伤,比如:ruby
线程不能独立执行,需要依赖进程吧,线程一定有所属的进程
java确实可以用setdaemon,主线程执行完后,子线程还在继续执行了一会,说明主线程结束后,子线程不是立即结束,而是继续执行了会,jvm有自己的线程
,还得等jvm本身结束了进程才会结束,jvm那个线程肯定是非守护的了
在python中使用线程是下下策,使用场景很有限,通常用aio和subprocess替代,aio是爬虫的重要前置知识之一,subprocess ←用来规避gil的限制 最大化利用处理器
你为啥用_thread里的东西,你换成threading.Thread试试加了下划线前缀的包是python不希望你用的,_thread默认创建的是守护线程,和threading.Thread本身行为就不一样
,主线程和其它线程 完全一样,cpython严格来说不能称之为解释器
主线程提前结束,其他线程还能继续执行么?就像ui线程,不对 cpython可以 jvm不行,ui线程结束了,只有当所有非守护进程结束 进程才会结束,只有当所有非守护进程结束 进程才会结束
我用pycharm执行一个脚本,这是个进程吧,严格来说 这是一个cpython进程,脚本本身只是一个文本文件,不能被进程加载器加载
因为python万物皆对象 变量皆指针,变量存在栈中,指向堆内存,java不是这样的,java有基础类型 不是对象,比如int就是基础类型 不是对象 它的包装类型integer是对象,java的基础类型都是存在栈
这个主线程和其他线程没什么区别,就是程序运行的入口这一点区别,从这个main入口进去后,后面线程发展都是随机的,main死了,其他线程可能还活着,
所有非守护线程结束时,进程不一定会死,有可能在死前做垃圾回收等清理工作因为jvm做的垃圾回收,jvm的运行建立在进程仍然存活的前提下,守护线程处理垃圾回收等善后工作
守护线程 是jvm/cpython这一层引入的概念 还得看vm的实现

但是我执行的时候,1秒就结束了,这个sleep好像没起到作用,这一秒 就在做这些事:main结束后 jvm会做一些别的工作包括垃圾回收啥的 这期间仍有时间执行守护线程的代码,垃圾回收啥的守护线程执行完后进程就结束了,这时代码中设置的守护线程可能还没有执行或者执行了一点。
有两种可能:守护线程立即被调度 sleep执行了 但因为主线程结束守护线程随即被杀死 2.守护线程没有立即调度 sleep压根没有执行
甚至连c,在main执行前后也会做很多你察觉不到的活

浙公网安备 33010602011771号