python 并发专题(一):并发基础相关概念,术语等
一、线程
1.概念
线程是程序执行流的最小执行单位,是行程中的实际运作单位。
进程是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者。可以说,进程中包含了多个可以同时运行的线程。
2.特点
线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所 拥有的全部资源。
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
3 线程的生命周期
线程被创建以后不是直接就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,他要经历新建、就绪、运行、阻塞和死亡5种状态
4 单线程和多线程
单线程,顾名思义即是只有一条线程在执行任务
多线程,创建多条线程同时执行任务,
5 多线程
主线程,子线程
多线程运行特点
引用自 主线程退出对子线程的影响--YuanLi 的一段话:
对于程序来说,如果主进程在子进程还未结束时就已经退出,那么Linux内核会将子进程的父进程ID改为1(也就是init进程),当子进程结束后会由init进程来回收该子进程。
主线程退出后子线程的状态依赖于它所在的进程,如果进程没有退出的话子线程依然正常运转。如果进程退出了,那么它所有的线程都会退出,所以子线程也就退出了。
三种情况
主线程退出,进程等待所有子线程执行完毕后才结束
进程启动后会默认产生一个主线程,默认情况下主线程创建的子线程都不是守护线程(setDaemon(False))。因此主线程结束后,子线程会继续执行,进程会等待所有子线程执行完毕后才结束
主线程结束后进程不等待守护线程完成,立即结束
当设置一个线程为守护线程时,此线程所属进程不会等待此线程运行结束,进程将立即结束。守护线程也结束。
注意:子线程会继承父线程中daemon的值,即守护线程开启的子线程仍是守护线程
主线程等待子线程完成后结束
6 线程池
线程池基本原理:
我们把任务放进队列中去,然后开N个线程,每个线程都去队列中取一个任务,执行完了之后告诉系统说我执行完了,然后接着去队列中取下一个任务,直至队列中所有任务取空,退出线程。
Python
中已经有了threading
模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程,而同时只允许3个线程在运行,但是20个线程都需要创建和销毁,线程的创建是需要消耗系统资源的,有没有更好的方案呢?其实只需要三个线程就行了,每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行。信号量(BoundedSemaphore类) 互斥锁同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据,比如厕所有3个坑, 那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去
7 GIL 全局解释器
在非python环境中,单核情况下,同时只能有一个任务执行。多核时可以支持多个线程同时执行。但是在python中,无论有多少个核同时只能执行一个线程。究其原因,这就是由于GIL的存在导致的。
GIL的全程是全局解释器,来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看做是“通行证”,并且在一个python进程之中,GIL只有一个。拿不到线程的通行证,并且在一个python进程中,GIL只有一个,拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有,因为cpython调用的是c语言的原生线程,所以他不能直接操作cpu,而只能利用GIL保证同一时间只能有一个线程拿到数据。而在pypy和jpython中是没有GIL的python在使用多线程的时候,调用的是c语言的原生过程。
8 同步锁、死锁以及互斥锁(线程安全问题)
互斥锁(同步锁)同时只允许一个线程更改数据
死锁:在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
二、进程
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
1.概念
进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。
进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。
2.特点
动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
并发性:任何进程都可以同其他进程一起并发执行。
独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。
3.生命周期
就绪(Ready)状态:当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
执行/运行(Running)状态:当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
阻塞(Blocked)状态:正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
4 多进程
同理,多进程就是指计算机同时执行多个进程,一般是同时运行多个软件。
父进程和子进程
前后两个进程各自有自己的地址空间,形式上有点像把一个文件拷贝了一个副本。虽然资源也相互独立,但拷贝时父进程执行过程已生成的数据,子进程也拷了一份。说简单点像一个执行到半路的程序突然在系统中多出了一个孪生兄弟,什么都跟自己一样,但要管自己叫老爸。
父进程和子进程先后执行的问题,是这样的,在fork之后,是父进程先执行,然后一个时间片到达之后就是子进程再执行了。
每一个子进程都有一个父进程,当进程终止或者结束的时候,都会给父进程发送一个SIGCHLD信号,系统默认是父进程忽略这个信号,如果父进程希望被告知其子进程的这种状态改变,则应该捕获这个信号,捕捉函数一般是wait函数来取得子进程ID和子进程状态。
若父进程退出,子进程尚未结束,则子进程会被init进程领养,也就是说init进程将成为该子进程的父进程。(父进程退出,默认下,未结束的子进程不退出)
守护进程
1、守护子进程
主进程创建守护进程
其一:守护进程会在主进程代码执行结束后就终止
其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
守护子进程、非守护子进程并存
p1是守护子进程,p2是非守护子进程,当主进程执行完毕(注意之类主进程还没有退出,因为还有p2非守护进程),p1守护进程也就退了,但是还有一个p2非守护进程,所以p2会执行自己的代码任务,当p2执行完毕,那么主进程也就退出了,进而整个程序就退出了
5 进程池
当需要创建的子进程数量不多时,可以直接动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以生成进程池。
初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;
但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行
三、协程
概念:
协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。
特点:
- 必须在只有一个单线程里实现并发
- 修改共享数据不需加锁
- 用户程序里自己保存多个控制流的上下文栈
- 附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))
四、阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
五、异步与同步
同步(synchronous): 所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。
简言之,要么成功都成功,失败都失败,两个任务的状态可以保持一致。
异步(asynchronous):所谓异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
六、并发与并行
并行(Parallelism)
并行:指两个或两个以上事件(或线程)在同一时刻发生,是真正意义上的不同事件或线程在同一时刻,在不同CPU资源呢上(多核),同时执行。
特点
- 同一时刻发生,同时执行。
- 不存在像并发那样竞争,等待的概念。
并发(Concurrency)
指一个物理CPU(也可以多个物理CPU) 在若干道程序(或线程)之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。
特点
- 微观角度:所有的并发处理都有排队等候,唤醒,执行等这样的步骤,在微观上他们都是序列被处理的,如果是同一时刻到达的请求(或线程)也会根据优先级的不同,而先后进入队列排队等候执行。
- 宏观角度:多个几乎同时到达的请求(或线程)在宏观上看就像是同时在被处理。
参考链接
https://blog.csdn.net/qq_33567641/article/details/81947832
https://www.cnblogs.com/linuxAndMcu/p/11064916.html
https://www.jianshu.com/p/6fc0d87b838c
https://blog.csdn.net/u014590757/article/details/80376255
https://blog.csdn.net/u013210620/article/details/78710532
python 并发专题(一):并发基础相关概念,术语等的更多相关文章
- Java多线程专题1: 并发与并行的基础概念
合集目录 Java多线程专题1: 并发与并行的基础概念 什么是多线程并发和并行? 并发: Concurrency 特指单核可以处理多任务, 这种机制主要实现于操作系统层面, 用于充分利用单CPU的性能 ...
- python多进程并发和多线程并发和协程
为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...
- Appium+python自动化(三十七)- 士兵突击许三多 - 多个appium服务启动,多个设备启动,多进程并发启动设备-并发测试 - 下(超详解)
简介 接着上一篇继续看一下如何并发测试以及并发测试的过程中,可能遇到的问题,在这里宏哥把宏哥遇到的和小伙伴或者童鞋们,一起分享一下. Appium端口检测 问题思考 经过前面学习,我们已经能够使用py ...
- Python 多线程教程:并发与并行
转载于: https://my.oschina.net/leejun2005/blog/398826 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global int ...
- 面试题_1_to_16_多线程、并发及线程的基础问题
多线程.并发及线程的基础问题 1)Java 中能创建 volatile 数组吗?能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组.我的意思是,如果改变引 ...
- Java 并发专题 :FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等
继续并发专题~ FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞. 由于:Fu ...
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...
- python之socketserver实现并发
python之socketserver实现并发 服务端 import socketserver #socketserver模块是用来实现并发 # 我们自己的类里一定要继承socketserver.Ba ...
- python 使用多进程实现并发编程/使用queue进行进程间数据交换
import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...
- java并发里的一些基础概念
转载自:https://my.oschina.net/hosee/blog/597934: 摘要: 本系列基于炼数成金课程,为了更好的学习,做了系列的记录. 本文主要介绍 1.高并发的概念,为以后系列 ...
随机推荐
- Java实现定时任务的三种简单方法
第一种方法: /** * 先定义一个任务每天执行的时间点,再写一个死循环,不断地拿当前时间和事先定义的时间去比对,若到时间则执行任务 */ @Test public void test1() { St ...
- @topcoder - SRM603D1L3@ SumOfArrays
目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 给定两个长度为 n 的数列 A, B.现你可以将两数列重排列,然后对 ...
- mysql小数类型
原文链接:https://blog.csdn.net/weixin_42047611/article/details/81449663 MySQL 中使用浮点数和定点数来表示小数. 浮点类型有两种,分 ...
- cb14a_c++_顺序容器的操作7_赋值与交换(swap)_vector转list
cb14a_c++_顺序容器的操作7_赋值与交换(swap) vector数据赋值给list, slist.assign(svec.begin(), svec.end());//这样可以转 svec- ...
- java递归遍历树结构目录
目录实体 private int id; private int pid; private String name; 递归遍历方法 private void getTree(Menu menu ,Li ...
- PyCharm远程连接服务器简明教程
转自本人知乎(https://zhuanlan.zhihu.com/p/149040742) 由于实验室的GPU都是放在远程服务器上,因此一直使用MobaXterm利用SSH远程跑实验,但是MobaX ...
- 他被称为"中国第一程序员",微软得不到他曾想毁了他,如今拜入武当修道
GitHub 15.4k Star 的Java工程师成神之路,不来了解一下吗! GitHub 15.4k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 15.4k Star ...
- PHP控制阿里云短信API接口实现短信群发功能
阿里云短信支持先使用后支付的原则,价格为4分半1条. 通过SDK可以与网站功能的绑定,实现响应的短信发送功能 现已统一合并升级为:消息服务. 消息服务 阿里云消息服务(Message Service, ...
- shell编程之系统环境变量
点后面加上空格+配置文件等价于source 配置文件 常见的系统环境变量的配置 Bash_profile和.bashrc存在在家目录下,~表示家目录 [root@localhost home]# cd ...
- Python表达式与生成式
Python表达式与生成式 前言 本章节中的所有知识点均为在不丧失代码可读性的前提下最大程度精简代码的一系列操作.其中涉及到一些性能问题(微乎其微)可以不做考虑. 三元表达式 三元表达式中有三个重要的 ...