day 32 操作系统、线程和进程(GIL锁)
一、操作系统/应用程序
- a. 硬件
- - 硬盘
- - CPU
- - 主板
- - 显卡
- - 内存
- - 电源
- ...
- b. 装系统(软件)
- - 系统就是一个由程序员写出来软件,该软件用于控制计算机的硬件,让他们之间进行相互配合。
- c. 安软件(安装应用程序)
- - 百度云
- - pycharm
二、并发和并行
- 并发,伪,由于执行速度特别快,人感觉不到停顿。
- 并行,真,创建10个人同时操作。
三、线程和进程
- a. 单进程、单线程的应用程序
- print('')
最简单
- b. 到底什么是线程?什么是进程?
- Python自己没有这玩意,Python中调用的操作系统的线程和进程。
- c. 单进程、多线程的应用程序
- 一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以创建多个线程(默认一个)
- import threading
- print('')
- 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)
查看gil切换指令
- 总结:
- 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、线程创建的越多越好吗?
不好,效率呈现抛物线形式
线程之间进行切换时,要做上下文管理(操作费时)
day 32 操作系统、线程和进程(GIL锁)的更多相关文章
- [并发编程 - 多线程:信号量、死锁与递归锁、时间Event、定时器Timer、线程队列、GIL锁]
[并发编程 - 多线程:信号量.死锁与递归锁.时间Event.定时器Timer.线程队列.GIL锁] 信号量 信号量Semaphore:管理一个内置的计数器 每当调用acquire()时内置计数器-1 ...
- 并发,并行,线程,进程,GIL锁
1.并发和并行 并发: 同时做某些事,但是强调同一时段做多件事 如:同一路口,发生了车辆要同时通过路面的时间. 并行: 互不干扰的在同一时刻做多件事 如:同一时刻,同时有多辆车在多条车道上跑,即同时发 ...
- 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型
本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...
- 线程 Thread类 GIL锁 信号量 Event事件
线程的开启方法 进程是操作系统调度的最小单位,一个进程最少有一个主线程,而一个进程中可以开启多个线程 from threading import Thread def task(): print('A ...
- python3 线程调用与GIL 锁机制
转载
- 并发编程: GIL锁、GIL与互斥锁区别、进程池与线程池的区别
一.GIL 二.关于GIL性能的讨论 三.计算密集测试 四.IO密集测试 五.GIL与互斥锁 六.TCP客户端 七.进程池 八.进程什么时候算是空闲 九.线程池 一.GIL GIL Global In ...
- GIL锁、进程池与线程池
1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...
- Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池
Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...
- 线程守护进程与GIL
为何要用多线程 多线程指的是,在一个进程中开启多个线程,简单的讲:如果多个任务共用一块地址空间,那么必须在一个进程内开启多个线程.详细的讲分为4点: 1. 多线程共享一个进程的地址空间 2. 线程比进 ...
- GIL锁,线程池
内容梗概: 1.线程队列 2.线程池 3.GIL锁 1.线程队列 1.1先进先出队列(FIFO)import queueq = queue.Queue(3)q.put(1)q.put(2)q.put( ...
随机推荐
- 微软并发Key-Value存储库FASTER介绍
微软支持并发的Key-Value 存储库有C++与C#两个版本.号称迄今为止最快的并发键值存储.下面是C#版本翻译: FASTER C#可在.NET Framework和.NET Core中运行,并且 ...
- 委托事件(jQuery)
<div class="content"> <ul> <li>1</li> <li>2</li> <l ...
- Java基础(37)ArrayList的remove方法
1.问题描述 给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 输入: s = "abcd& ...
- (三)快速添加touch事件
EasyTouch提供了类似UGUI的可视化点击事件,如button类似,此功能可以快速实现三维物体的旋转缩放.在场景中新建cube然后添加组件,输入quick会出现一下一个选项: quick dra ...
- Spring Boot项目在多环境下(开发、生产或测试环境)调用不同配置文件方式
写在前面 最近由于项目要求,原先的项目只有开发环境的项目配置,后来不利于线上测试,于是,最近对于SpringBoot这部分多环境配置在网上查找了相关资料,并实现了配置,于是为了防止遗忘,特在此进行总结 ...
- 【问题记录】VMware Tools是灰色的,不能安装
一.VMware Tools简介 VMware Tools 中包含一系列服务和模块,可在 VMware 产品中实现多种功能,从而使用户能够更好地管理客户机操作系统,以及与客户机操作系统进行无缝交互. ...
- BFM模型介绍及可视化实现(C++)
BFM模型介绍及可视化实现(C++) BFM模型基本介绍 Basel Face Model是一个开源的人脸数据库,其基本原理是3DMM,因此其便是在PCA的基础上进行存储的. 目前有两个版本的数据库( ...
- 虚拟机linux centos7 查找ip不到的设置
1.centos7 系统后查找ip信息,不用ifconfig -a 命令,开始使用ip Addr命令 输入ip Addr 命令后,并没有看到实际的ip地址,记住上述图片中红色标记的ens32 这个就是 ...
- 利用python的requests和BeautifulSoup库爬取小说网站内容
1. 什么是Requests? Requests是用Python语言编写的,基于urllib3来改写的,采用Apache2 Licensed 来源协议的HTTP库. 它比urllib更加方便,可以节约 ...
- Resource Path Location Type Target runtime Apache Tomcat v6.0 is not defined(项目报错)已解决
我换了开发工具后,导入的项目不是这里报错就是那里不错.不过,我喜欢.在tomcat里面部署项目后,定位到报错行时,总是提示我这句话:Description Resource Path Location ...