一个应用程序:软件
一个应用程序:可以创建多个进程(默认一个进程),一个进程可以创建多个线程(默认一个线程)
线程:工作的最小单元,共享进程中的所有资源,每个线程分担一点任务,最终完成最后的结果
进程:独立开辟内存 进程之间的数据隔离
总结: 1.操作系统帮助开发者操作硬件
2.程序员写好代码在操作系统上运行
任务特别多:
3.串行 一个个的去执行
1 写好代码
2 交给解释器运行
3 解释器读取代码,再交给操作系统执行,根据写的代码选择创建线程/进程去执行(单进程/单线程)
4.多线程的话
1 写好代码
2 交给解释器运行
3 解释器读取代码,再交给操作系统执行,根据写的代码选择创建线程/进程去执行(单进程/多线程)
GIL:全局解释器锁:用于限制一个进程中同一时刻只有一个线程被cpu调度
线程之间切换默认gil锁在执行100个cpu指令的时候就切换 还有一个就是过期时间
1 import sys 2 3 v = sys.getcheckinterval() 4 print(v)
Python多线程情况下:
计算密集型操作:效率低(GIL锁)
IO密集型操作:效率高
Python多进程情况下:
计算密集型操作:效率高(浪费资源)不得已而为之
IO密集型操作:效率高 (浪费资源)
Java多线程情况下:
计算密集型操作:效率高
IO密集型操作:效率高
Java多进程程情况下:(Java程序员一般不写多进程)
计算密集型操作:效率高
IO密集型操作:效率高
自己画了图,图解非常清晰很容易理解(对比Java)
实例一:主线程默认等子线程执行完毕
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import threading 5 import time 6 7 def func(arg): 8 time.sleep(arg) 9 print(arg) 10 11 12 t1 = threading.Thread(target=func, args=(3,)) 13 t1.start() 14 15 t2 = threading.Thread(target=func, args=(9,)) 16 t2.start() 17 18 print(‘123‘)
执行结果:
123 3 9
实例二、主线程不再等子线程,主线程终止则所有子线程终止
1 # def func(arg): 2 # time.sleep(arg) 3 # print(arg) 4 # 5 # 6 # t1 = threading.Thread(target=func, args=(3,)) 7 # t1.setDaemon(True) # 不等子线程 8 # t1.start() 9 # 10 # t2 = threading.Thread(target=func, args=(9,)) 11 # t2.setDaemon(True) 12 # t2.start() 13 # 14 # print(123) 15 16 # 123
实例三、开发者可以控制主线程等待子线程(最多等待时间)
1 # def func(arg): 2 # time.sleep(10) 3 # print(arg) 4 # 5 # 6 # print(‘创建子线程t1‘) 7 # t1 = threading.Thread(target=func, args=(3,)) 8 # t1.start() 9 # t1.join() # 让主线程在这里等着,等到子线程t1执行完毕继续往下走 10 # # t1.join(1) # 主线程最多等1s 11 # print(‘创建子线程t2‘) 12 # t2 = threading.Thread(target=func, args=(9,)) 13 # t2.start() 14 # t2.join() # 让主线程在这里等着,等到子线程t2执行完毕继续往下走 这样搞纯粹没意义了开线程没卵用就是串行了 15 # # t2.join(1) # 主线程最多等1s 16 # print(123) 17 # 创建子线程t1 18 # 3 19 # 创建子线程t2 20 # 9 21 # 123
实例四、获取线程名称
1 # def func(arg): 2 # # 获取当前执行该函数的线程的名称 3 # t = threading.current_thread() 4 # name = t.getName() 5 # print(name, arg) 6 # 7 # 8 # t1 = threading.Thread(target=func, args=(3,)) 9 # t1.setName(‘t111111‘) 10 # t1.start() 11 # 12 # 13 # t2 = threading.Thread(target=func, args=(9,)) 14 # t2.setName(‘t222222‘) 15 # t2.start() 16 # 17 # print(123)
实例五、线程本质
1 # 先打印 3?还是123? 这个不确定 要看cpu现在忙不忙,有没有空余时间 2 # def func(arg): 3 # print(arg) 4 # 5 # 6 # t1 = threading.Thread(target=func, args=(3,)) 7 # t1.start() # 是开始运行线程吗? 不是 8 # # start告诉cpu 我已经准备好了,你可以调度我了 9 # 10 # 11 # print(123)
实例六、面向对象版本的线程
自己写run方法让自己的线程去执行自己想执行的任务,就不走Thread里边内置的run方法了
1 class MyThread(threading.Thread): 2 # 看源码发现的 3 """ 4 self._target = target 5 if self._target: 6 self._target(*self._args, **self._kwargs) 7 """ 8 def run(self): 9 print(‘11111‘, self._args, self._kwargs) 10 11 12 # def func(arg): 13 # print(arg) 14 15 16 # t1 = MyThread(target=func, args=(11,)) 17 t1 = MyThread(args=(11,), kwargs={‘name‘: 1}) 18 t1.start() 19 # 11111 (11,) {‘name‘: 1}
原文:https://www.cnblogs.com/Alexephor/p/11222944.html