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( ...
随机推荐
- 如何用github搭建博客
新建项目 创建仓库 仓库名称:一定要是你的用户名+github.io 如:用户名:zhangsan 那么仓库地址: zhangsan,github.io 打开新创建的仓库,点击settings 下拉至 ...
- [转载]制作QT字库文件
原文地址:http://www.cnblogs.com/liu_xf/archive/2011/07/05/2098144.htm 摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的, ...
- postman的基本用法,请求,断言,环境变量
postman基本用法 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 它提供功能强大的 Web API & HTTP 请求调试. 它能够发送任何类型的HTT ...
- 【并发编程】Volatile原理和使用场景解析
目录 一个简单列子 Java内存模型 缓存不一致问题 并发编程中的"三性" 使用volatile来解决共享变量可见性 volatile和指令重排(有序性) volatile和原子性 ...
- Linux中vi命令的详细总结
vi命令的使用 首先可以新建一个文件夹 touch 1.txt 之后通过vi命令进入其中 vi 1.txt 进入其中开始编辑,按下a键可以进行输入. 随便输入一些东西(暂时不支持中文) 非输入模式 ...
- 入门Android底层需要的一些技能
<Android的设计与实现> Android框架层<Linux系统编程手册> Linux系统编程<Android内核剖析> 编译框架和romC语言和Linux内核 ...
- CSS汇总之CSS选择器
要使用css对HTML页面中的元素实现一对一,一对多或者多对一的控制,这就需要用到CSS选择器. 一.通配符选择器 语法:*{ } 说明:通配符选择器可以选择页面上所有的html标签(包括body,h ...
- BZOJ 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱(这是我写过最骚气的dp!)
题目描述 贝西和邦妮找到了一个藏宝箱,里面都是金币! 但是身为两头牛,她们不能到商店里把金币换成好吃的东西,于是她们只能用这些金币来玩游戏了. 藏宝箱里一共有N枚金币,第i枚金币的价值是Ci.贝西 ...
- Java环境变量配置教程
Windows 10 Java环境变量配置教程 目前Windows 10系统已经很成熟,大多数人开发都在Windows 10系统下进行开发,于是乎我做一下Java环境变量在Windows 10配下的 ...
- Python 基础之socket编程(一)
Python 基础之socket编程(一) 可以进行通信玩儿了,感觉不错不错,网络通信就像打电话,我说一句你听一句之后,你再说一句,我听一句,就这样.....下去了.不扯淡了,来来来,看看今天都搞了点 ...