并发,并行,线程,进程,GIL锁
1.并发和并行
并发:
同时做某些事,但是强调同一时段做多件事
如:同一路口,发生了车辆要同时通过路面的时间.
并行:
互不干扰的在同一时刻做多件事
如:同一时刻,同时有多辆车在多条车道上跑,即同时发生的概念.
解决并发:
1.队列:即排队
缓冲区:排成的队列
2.争抢:锁机制,在同一时刻CPU只能为一个进程服务
3.并行:开启多个CPU,同时提供服务
在电脑中,如果并发,由于执行速度特别快,所以人感觉不到停顿,认为是同时进行的.
如果并行,就是同时进行的,即创建多个同时操作
2.进程和线程
a.在实现了线程的操作系统中,线程是操作系统能够运算调度的最小单位.
b.线程被包含在进程中,是进程的实际运作单位.
c.一个程序的执行实例就是一个进程.
d.一个应用程序(软件)可以有多个进程(默认只有一个),一个进程可以有多个线程(默认只有一个).
2.1进程
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.进程是线程的容器.
当运行一个程序时,OS会创建一个进程,它会使用系统资源(CPU,内存和磁盘空间)和OS内核中的数据结构(文件,网络连接,用量统计等).
进程之间是互相隔离的,即一个进程无法访问其他进程中的内容,也无法操作其他进程.
操作系统会跟踪所有正在运行的进程,给每个进程一小段运行时间,然后切换到其他进程,这样既可以做到公平又可以响应用户操作.
2.2线程
进程是独立的,进程间不能随便共享数据
线程是进程中的,同一进程内的线程可以共享进程的资源,每一个线程有自己独立的堆栈.
线程的状态:
就绪:线程一旦运行,就在等待被调度.
运行:线程正在运行
阻塞:线程等待外部事件发生而无法运行,如I/O操作.
终止:线程完成或退出,或被取消.
python中的线程:
python线程开发使用threading库
def __init__(self,group=None,target=None,name=None,args=(),kwargs=None,*,daemon=None)
target:线程调用的对象,就是目标函数
name:为线程起的名字
args:为目标函数传递实参,元组
kwargs:为目标函数关键字传参,字典.
1.线程的基本使用:
import threading def func(arg):
print(arg) t = threading.Thread(target=func,args=(,))
t.start()
2.主线程默认等子线程执行完毕
import time
import threading def func(arg):
time.sleep(arg)
print(arg) t1 = threading.Thread(target=func,args=(,))
t1.start() t2 = threading.Thread(target=func,args=(,))
t2.start()
13 print(123)
3.主线程不再等,主线程终止则所有子线程终止
import time
import threading def func(arg):
time.sleep()
print(arg) t1 = threading.Thread(target=func,args=(,))
t1.setDaemon(True)
t1.start() t2 = threading.Thread(target=func,args=(,))
t2.setDaemon(True)
t2.start() print()
4.控制主线程等待子线程(最多等待时间)
import threading
import time def func(arg):
time.sleep(0.1)
print(arg) print("创建子线程t1") t1 = threading.Thread(target=func,args=(,))
t1.start()
t1.join() print("创建子线程t2")
t2 = threading.Thread(target=func,args=(,))
t2.start()
t2.join() print() #join中无参数,让主线程在这里等着,等到子线程t1执行完毕,才继续往下走
#join中有参数,让主线程在这里最多等待n秒,无论是否执行完毕,都会继续往下走
5.线程名称
import threading def func(arg):
#获取当前执行该函数的线程的对象
t = threading.current_thread()
#根据当前线程对象获取当前线程名称
name = t.getName()
print(name,arg) t1 = threading.Thread(target=func,args=(,))
t1.setName("")
t1.start() t2 = threading.Thread(target=func,args=(,))
t2.setName("")
t2.start() print()
t.start()并不是开始运行线程,而是告诉CPU已经准备就绪,可以调度了.
6.面向对象版本的多线程
import threading #多线程方式1:
def func(arg):
print(arg) t1 = threading.Thread(target=func,args=(,))
t1.start() #多线程方式2:
class MyThread(threading.Thread): def run(self):
print(,self._args,self._kwargs) t1 = MyThread(args=(,))
t1.start() t2 = MyThread(args=(,))
t2.start() print("end")
python多线程情况下:
计算密集型操作:效率低(GIL锁)
IO操作:效率高
python多进程的情况下:
计算密集型操作:效率高(浪费资源)
IO操作:效率高(浪费资源)
一般写时:
IO密集型用多线程:文件/输入输出/socket网络通信
计算密集型用多进程
Java多线程情况下:
计算密集型操作:效率高
IO操作:效率高
Python多进程的情况下:
计算密集型操作:效率高(浪费资源)
IO操作:效率高,浪费资源
3.GIL锁
GIL锁,全局解释器锁,用于限制一个进程中同一时刻只有一个线程被CPU调度,默认GIL锁在执行100个CPU指令.
多进程可以充分使用CPU的两个内核,而多线程却不能充分使用CPU的两个内核.
原因:cpython解释器中存在GIL(全局解释器锁),它的作用就是保证同一时刻只有一个线程可以执行代码.
因此造成了使用多线程的时候无法实现并行.
解决方案:
1.更换解释器,比如使用jpython(java实现的python解释器)
2.使用多进程完成多任务的处理
常见GIL面试题:
描述Python GIL的概念,以及它对python多线程的影响,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因
python语言和GIL没有关系,仅仅是由于历史原因在Cpython虚拟机(解释器),难以移除GIL.
GIL:全局解释器锁.每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程可以执行代码.
线程释放GIL锁的情况:在IO操作等可能会引起阻塞的syste, call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL
python使用多进程是可以利用多核的CPU资源的.
多线程爬去比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁.
结论:
1.在处理像科学计算这类需要持续使用CPU的任务的时候,单线程会比多线程快.
2.在处理像IO操作等可能引起阻塞的这类任务的时候,多线程会比单线程快.
import time
import threading lock = threading.Rlock()
n = 10 def task(i):
print("这段代码不加锁",i)
lock.acquire() #加锁, 此区域的代码同一时刻只能由一个线程执行.
global n
print("当前线程",i,"修改n值为:",n)
lock.release() #释放锁 for i in range(10):
t = threading.Thread(target=task,args=(i,))
t.start()
并发,并行,线程,进程,GIL锁的更多相关文章
- 并发编程 - 线程 - 1.互斥锁/2.GIL解释器锁/3.死锁与递归锁/4.信号量/5.Event事件/6.定时器
1.互斥锁: 原理:将并行变成串行 精髓:局部串行,只针对共享数据修改 保护不同的数据就应该用不用的锁 from threading import Thread, Lock import time n ...
- 15.python并发编程(线程--进程--协程)
一.进程:1.定义:进程最小的资源单位,本质就是一个程序在一个数据集上的一次动态执行(运行)的过程2.组成:进程一般由程序,数据集,进程控制三部分组成:(1)程序:用来描述进程要完成哪些功能以及如何完 ...
- python之并发编程(线程\进程\协程)
一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...
- Python 线程----线程方法,线程事件,线程队列,线程池,GIL锁,协程,Greenlet
主要内容: 线程的一些其他方法 线程事件 线程队列 线程池 GIL锁 协程 Greenlet Gevent 一. 线程(threading)的一些其他方法 from threading import ...
- 线程有gil锁
gil锁作用: 遇到阻塞( 比如 recv() , accept() )就切换
- 【深入理解JAVA虚拟机】第5部分.高效并发.2.线程安全和锁优化
1 概述 对于这部分的主题“高效并发”来讲,首先需要保证并发的正确性,然后在此基础上实现高效. 2 线程安全 <Java Concurrency In Practice> 的作者Brian ...
- 网络编程基础----并发编程 ---守护进程----同步锁 lock-----IPC机制----生产者消费者模型
1 守护进程: 主进程 创建 守护进程 辅助主进程的运行 设置进程的 daemon属性 p1.daemon=True 1 守护进程会在主进程代码执行结束后就终止: 2 守护进程内无法再开启子进程 ...
- Python的并发并行[3] -> 进程[0] -> subprocess 模块
subprocess 模块 0 模块描述 / Module Description From subprocess module: """Subprocesses wit ...
- Python的并发并行[3] -> 进程[1] -> 多进程的基本使用
多进程的基本使用 1 subprocess 常用函数示例 首先定义一个子进程调用的程序,用于打印一个输出语句,并获取命令行参数 import sys print('Called_Function.py ...
随机推荐
- 该内存不能read 或written数值 叙述(居然还有具体的讲究)
该内存不能read 或written数值 叙述 0 0x0000 作业完成. 1 0x0001 不正确的函数. 2 0x0002 系统找不到指定的档案. 3 0x0003 系统找不到指定的路径. 4 ...
- Qt优雅地结束线程(两种方法都是用Mutex锁住bool变量进行修改,然后由bool变量控制耗时动作的退出,即正常退出)
如果一个线程运行完成,就会结束.可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它.不恰当的中止往往会引起一些未知错误.比如:当关闭主界面的时候,很有可能次线程正在运行,这时 ...
- Bitmap的读写和几个小儿科的滤镜效果~
闲来玩玩图像处理,拿破仑说过:“不想自己实现滤镜的美工不是好程序员~~#@!*^...#&!@......” 因为在学校做过很多美工的工作,而且从小就喜欢画画所以对图像相关的东西都还比较感兴 ...
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发1-准备工作
/****** Object: 新闻表 Script Date: 2017/9/2 星期六 15:11:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENT ...
- Zabbix集成Cloud Alert(睿象云)实现电话短信预警
Zabbix 集成 睿象云智能告警平台 CA ( Cloud Alert ) 一 .简介与前期了解 Cloud Alert 通过应用,接入监控系统/平台的告警,集中管理您的告警,统一分派通知,统一分析 ...
- sqlserver 表值函数与标量值函数
除了在我们常用的程序开发中要用到函数外,在sql语句中也常用到函数,不论哪种,思想都没有变,都是为了封装,可复用. 创建的方法和整体结构都大体相同,都少不了函数名,函数的形参,返回值等这些. 一.表值 ...
- C++标准库(体系结构与内核分析)(侯捷第一讲)
一.C++标准库介绍 C++标准库:C++ Standard Library C++标准库与STL有什么关系: STL:Standard Template Library STL包含6大部件,基本占标 ...
- 使用docker启动mysql
安装docker 查询mysql版本, docker search mysql 拉取指定版本的镜像 docker pull NAME 启动镜像, 第一次启动最少需要指定MYSQL_ROOT_PASSW ...
- 大白话五种IO模型
目录 一.I/O模型介绍 二.阻塞I/O模型 2.1 一个简单的解决方案 2.2 该方案的问题 2.3 改进方案 2.4 改进后方案的问题 三.非阻塞I/O模型 3.1 非阻塞I/O实例 四.多路复用 ...
- 分享常见的HTTP状态码
本内容摘抄自RUNOOB.COM 当浏览一个网页时,浏览器会向网页所在服务器发出请求.当浏览器确定接收并显示网页之前,此网页所在的服务器会返回一个含有HTTP状态码(HTTP Status Code) ...