一、操作系统/应用程序
a. 硬件 - 硬盘 - CPU - 主板 - 显卡 - 内存 - 电源 ... b. 装系统(软件) - 系统就是一个由程序员写出来软件,该软件用于控制计算机的硬件,让他们之间进行相互配合。 c. 安软件(安装应用程序) - QQ - 百度云 - pycharm
二、并发和并行
并发,伪,由于执行速度特别快,人感觉不到停顿。
并行,真,创建10个人同时操作。
三、线程和进程
a. 单进程、单线程的应用程序
print('666')
b. 到底什么是线程?什么是进程?
Python自己没有这玩意,Python中调用的操作系统的线程和进程。
c. 单进程、多线程的应用程序
一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以创建多个线程(默认一个)
import threading print('666') def func(arg): print(arg) t = threading.Thread(target=func) t.start() print('end')
d. 故事: Alex甄嬛西游传
总结:
1. 操作系统帮助开发者操作硬件。
2. 程序员写好代码在操作系统上运行(依赖解释器)。
import threading import requests import uuid url_list = [ 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', ] def task(url): ret = requests.get(url) file_name = str(uuid.uuid4()) + '.jpg' with open(file_name, mode='wb') as f: f.write(ret.content) for url in url_list: task() """ - 你写好代码 - 交给解释器运行: python s1.py - 解释器读取代码,再交给操作系统去执行,根据你的代码去选择创建多少个线程/进程去执行(单进程/单线程)。 - 操作系统调用硬件:硬盘、cpu、网卡.... """
import threading import requests import uuid url_list = [ 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', ] def task(url): ret = requests.get(url) file_name = str(uuid.uuid4()) + '.jpg' with open(file_name, mode='wb') as f: f.write(ret.content) for url in url_list: t = threading.Thread(target=task,args=(url,)) t.start() """ - 你写好代码 - 交给解释器运行: python s2.py - 解释器读取代码,再交给操作系统去执行,根据你的代码去选择创建多少个线程/进程去执行(单进程/4线程)。 - 操作系统调用硬件:硬盘、cpu、网卡.... """
Python多线程情况下: - 计算密集型操作:效率低。(GIL锁) - IO操作: 效率高 Python多进程的情况下: - 计算密集型操作:效率高(浪费资源)。 不得已而为之。 - IO操作: 效率高 (浪费资源)。 以后写Python时: IO密集型用多线程: 文件/输入输出/socket网络通信 计算密集型用多进程。 扩展: Java多线程情况下: - 计算密集型操作:效率高。 - IO操作: 效率高 Python多进程的情况下: - 计算密集型操作:效率高(浪费资源)。 - IO操作: 效率高 浪费资源)。
四、Python中线程和进程(GIL锁)
GIL锁,全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。
扩展:默认GIL锁在执行100个cpu指令(过期时间)。
五、python线程编写
# by luffycity.com import threading # #################### 1. 计算密集型多线程无用 #################### # v1 = [11,22,33] # +1 # v2 = [44,55,66] # 100 # # # def func(data,plus): # for i in range(len(data)): # data[i] = data[i] + plus # # t1 = threading.Thread(target=func,args=(v1,1)) # t1.start() # # t2 = threading.Thread(target=func,args=(v2,100)) # t2.start() # #################### 2. IO操作 多线程有用 #################### # import threading # import requests # import uuid # # url_list = [ # 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', # 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', # 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', # ] # # def task(url): # ret = requests.get(url) # file_name = str(uuid.uuid4()) + '.jpg' # with open(file_name, mode='wb') as f: # f.write(ret.content) # # for url in url_list: # # t = threading.Thread(target=task,args=(url,)) # t.start()
# by luffycity.com import threading # ###################### 1.线程的基本使用 ################# # def func(arg): # print(arg) # # # t = threading.Thread(target=func,args=(11,)) # t.start() # # # print(123) # ###################### 2.主线程默认等子线程执行完毕 ################# # import time # def func(arg): # time.sleep(arg) # print(arg) # # # t1 = threading.Thread(target=func,args=(3,)) # t1.start() # # t2 = threading.Thread(target=func,args=(9,)) # t2.start() # # print(123) # ###################### 3.主线程不再等,主线程终止则所有子线程终止 ################# # import time # def func(arg): # time.sleep(2) # print(arg) # # t1 = threading.Thread(target=func,args=(3,)) # t1.setDaemon(True) # t1.start() # # t2 = threading.Thread(target=func,args=(9,)) # t2.setDaemon(True) # t2.start() # # print(123) # ###################### 4.开发者可以控制主线程等待子线程(最多等待时间) ################# # import time # def func(arg): # time.sleep(0.01) # print(arg) # # print('创建子线程t1') # t1 = threading.Thread(target=func,args=(3,)) # t1.start() # # 无参数,让主线程在这里等着,等到子线程t1执行完毕,才可以继续往下走。 # # 有参数,让主线程在这里最多等待n秒,无论是否执行完毕,会继续往下走。 # t1.join(2) # # print('创建子线程t2') # t2 = threading.Thread(target=func,args=(9,)) # t2.start() # t2.join(2) # 让主线程在这里等着,等到子线程t2执行完毕,才可以继续往下走。 # # print(123) # ###################### 4.线程名称 ################# # def func(arg): # # 获取当前执行该函数的线程的对象 # t = threading.current_thread() # # 根据当前线程对象获取当前线程名称 # name = t.getName() # print(name,arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.setName('侯明魏') # t1.start() # # t2 = threading.Thread(target=func,args=(22,)) # t2.setName('刘宁钱') # t2.start() # # print(123) # ###################### 5.线程本质 ################# # 先打印:11?123? # def func(arg): # print(arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.start() # # start 是开始运行线程吗?不是 # # start 告诉cpu,我已经准备就绪,你可以调度我了。 # print(123) # ###################### 6.补充:面向对象版本的多线程 ################# # 多线程方式:1 (常见) # def func(arg): # print(arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.start() # 多线程方式:2 # class MyThread(threading.Thread): # # def run(self): # print(11111,self._args,self._kwargs) # # t1 = MyThread(args=(11,)) # t1.start() # # t2 = MyThread(args=(22,)) # t2.start() print('end')
# by luffycity.com import threading # ###################### 1.线程的基本使用 ################# # def func(arg): # print(arg) # # # t = threading.Thread(target=func,args=(11,)) # t.start() # # # print(123) # ###################### 2.主线程默认等子线程执行完毕 ################# # import time # def func(arg): # time.sleep(arg) # print(arg) # # # t1 = threading.Thread(target=func,args=(3,)) # t1.start() # # t2 = threading.Thread(target=func,args=(9,)) # t2.start() # # print(123) # ###################### 3.主线程不再等,主线程终止则所有子线程终止 ################# # import time # def func(arg): # time.sleep(2) # print(arg) # # t1 = threading.Thread(target=func,args=(3,)) # t1.setDaemon(True) # t1.start() # # t2 = threading.Thread(target=func,args=(9,)) # t2.setDaemon(True) # t2.start() # # print(123) # ###################### 4.开发者可以控制主线程等待子线程(最多等待时间) ################# # import time # def func(arg): # time.sleep(0.01) # print(arg) # # print('创建子线程t1') # t1 = threading.Thread(target=func,args=(3,)) # t1.start() # # 无参数,让主线程在这里等着,等到子线程t1执行完毕,才可以继续往下走。 # # 有参数,让主线程在这里最多等待n秒,无论是否执行完毕,会继续往下走。 # t1.join(2) # # print('创建子线程t2') # t2 = threading.Thread(target=func,args=(9,)) # t2.start() # t2.join(2) # 让主线程在这里等着,等到子线程t2执行完毕,才可以继续往下走。 # # print(123) # ###################### 4.线程名称 ################# # def func(arg): # # 获取当前执行该函数的线程的对象 # t = threading.current_thread() # # 根据当前线程对象获取当前线程名称 # name = t.getName() # print(name,arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.setName('侯明魏') # t1.start() # # t2 = threading.Thread(target=func,args=(22,)) # t2.setName('刘宁钱') # t2.start() # # print(123) # ###################### 5.线程本质 ################# # 先打印:11?123? # def func(arg): # print(arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.start() # # start 是开始运行线程吗?不是 # # start 告诉cpu,我已经准备就绪,你可以调度我了。 # print(123) # ###################### 6.补充:面向对象版本的多线程 ################# # 多线程方式:1 (常见) # def func(arg): # print(arg) # # t1 = threading.Thread(target=func,args=(11,)) # t1.start() # 多线程方式:2 # class MyThread(threading.Thread): # # def run(self): # print(11111,self._args,self._kwargs) # # t1 = MyThread(args=(11,)) # t1.start() # # t2 = MyThread(args=(22,)) # t2.start() print('end')
# by luffycity.com import time import threading lock = threading.RLock() n = 10 def task(i): print('这段代码不加锁',i) lock.acquire() # 加锁,此区域的代码同一时刻只能有一个线程执行 global n print('当前线程',i,'读取到的n值为:',n) n = i time.sleep(1) print('当前线程',i,'修改n值为:',n) lock.release() # 释放锁 for i in range(10): t = threading.Thread(target=task,args=(i,)) t.start()
暂时忘记知识点
import sys v1 = sys.getcheckinterval() print(v1)
总结: 1. 应用程序/进程/线程的关系? *****(面试题:进程/线程/协程的区别?) 2. 为什么要创建线程? 由于线程是cpu工作的最小单元,创建线程可以利用多核优势实现并行操作(Java/C#)。 注意:线程是为了工作。 3. 为什么要创建进程? 进程和进程之间做数据隔离(Java/C#)。 注意:进程是为了提供环境让线程工作。 4. Python
IO操作不占用CPU a. Python中存在一个GIL锁。 ***** - 造成:多线程无法利用多核优势。 - 解决:开多进程处理(浪费资源) 总结: IO密集型:多线程 计算密集型:多进程 b. 线程的创建 - Thread ***** - MyThread c. 其他 - join ***** - setDeanon ***** - setName ***** - threading.current_thread() ***** d. 锁 - 获得 - 释放
6、线程创建的越多越好吗?
不好,效率呈现抛物线形式
线程之间进行切换时,要做上下文管理(操作费时)