并发编程前言:

1、网络应用

1)爬虫 直接应用并发编程;

2)网络框架 django flask tornado 源码-并发编程

3)socketserver 源码-并发编程

2、运维领域

1)自动化开发-运维开发(机器的批量管理,任务的批量执行等)

一、操作系统/应用程序

a、硬件

- 硬盘

- CPU

- 主板

- 显卡

- 内存

- 电源

. . . . . .

b、装系统(软件)

- 系统就是一个由程序员写出来的软件,该软件用于控制计算机的硬件,让他们之间进行相互配合。

c、安软件(安装应用程序)

- QQ

- 百度云

- pycharm

. . . . . .

二、并行与并发

并发,是伪的,由于执行速度特别快,人感觉不到停顿;

并行,是真的,创建10个人同时操作;

并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑(资源够用,比如三个线程,四核的cpu);

并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核cpu资源)同时只能过一个人,A走一段后,让给B,B用完继续给A,交替使用,目的是提高效率;

区别:

并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。

并发是从宏观上,在一个时间段上可以看成是同时执行的。

三、线程和进程

a、单进程、单线程的应用程序,比如:

  print('666')

b、到底什么是线程?什么是进程?

python自己没有这玩意,python中调用的操作系统的线程和进程。

c、单进程、多线程的应用程序,比如:

    import threading
print('') def func(arg):
print(arg)
t = threading.Thread(target=func,args=(11,)) # 创建一个线程
t.start()

  一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以创建多个线程(默认一个)。

d、故事:Alex甄嬛西游传

总结:

1)操作系统帮助开发者操作硬件;

2)程序员写好代码在操作系统上运行(依赖解释器);

3)任务比较多时,可将以前代码写法作如下改进:

    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锁)

GIL锁:python内置的一个全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。

扩展:默认GIL锁再执行100个cpu指令(过期时间)。

    import sys
v = sys.getcheckinterval()
print(v) #

查看方法

  问题1:为什么有这把GIL锁?

python语言的创始人在开发这门语言时,目的是快速把语言开发出来,如果加上GIL锁(c语言加锁),切换时按照100条字节指令来进行线程间的切换。

问题2:进程和线程的区别?

线程,线程是cpu工作的最小单元;

进程,进程是cpu资源分配的最小单元,为线程提供一个资源共享的空间;

一个进程中可以有多个线程,一个进程中默认有一个主线程;

对于python来说,它的进程和线程和其他语言有差异,有GIL锁。它保证一个进程中同一时刻只有一个线程被cpu调度;

IO密集型操作可以使用多线程,计算密集型可以使用多进程;

  问题3:线程创建的越多越好吗?

不是,线程之间进行切换,要做上下文管理。

五、python线程编写

1、线程的基本使用,如下示例:

  import threading
  def func(arg):
  print(arg)   t = threading.Thread(target=func,args=(11,)) # 创建一个子线程
  t.start()   print(123)
  #
  #
  # 程序结束

2、主线程默认等子线程执行完毕,才结束程序,如下示例:

    import threading
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=(6,))
t2.start()
# 3 # 程序开始3秒后
# 6 # 程序开始6秒后
# 程序结束

3、主线程不再等,当主线程终止则所有子线程也终止,使用setDaemon(True),如下示例:

    import threading
import time
def func(arg):
time.sleep(arg)
print(arg) t1 = threading.Thread(target=func,args=(3,))
t1.setDaemon(False) # 主线程等待此子进程
t1.start() t2 = threading.Thread(target=func,args=(6,))
t2.setDaemon(True) # 主线程不再等待此子进程
t2.start() print(123)
#
#
# # 程序结束

4、开发者可以控制主线程等待子线程(最多等待时间),使用join(n),如下示例:

    import threading
import time
def func(arg):
time.sleep(arg)
print(arg) print('创建子线程t1')
t1 = threading.Thread(target=func,args=(3,))
t1.start()
t1.join(2)
# 无参数,让主线程在这里等着,等到子线程t1执行完毕,才可以继续往下走。
# 有参数,让主线程在这里最多等待n秒,无论是否执行完毕,会继续往下走。 print('创建子线程t2')
t2 = threading.Thread(target=func,args=(1,))
t2.start()
t2.join(3) # 让主线程在这里等着,最多等待3秒,会继续往下走,
# 若子线程t2不到3秒就执行完毕,则子线程执行完毕主线程就往下走。 print(123)
# 创建子线程t1
# 创建子线程t2
#
#
#
# 程序结束

5、线程名称,如下示例:

    import threading
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)
# 郭德纲 11
# 孙红雷 22
#

6、线程本质,如下示例:

    # 先打印:11?123?
import threading
def func(arg):
print(arg) t1 = threading.Thread(target=func,args=(11,))
t1.start()
# start 是开始运行线程吗?不是
# start 告诉cpu,我已经准备就绪,你可以调度我了。
print(123)

7、面向对象版本的多线程,如下示例:

    import threading
def func(arg):
print(arg) t1 = threading.Thread(target=func,args=(11,))
t1.start()

常见创建多线程的方式:

    import threading
class MyThread(threading.Thread):
def run(self):
print(11111,self._args,self._kwargs) t1 = MyThread(args=(11,))
t1.start() # 在cpu内部,如果要调度这个线程的话会执行这个对象的run方法 t2 = MyThread(args=(22,))
t2.start() print('end')
# 11111 (11,) {}
# 11111 (22,) {}
# end

面向对象方式(一般不用,了解即可):

8、多线程

1)计算密集型多线程无用,如下示例:

    import threading
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操作,多线程有用(IO操作不占用cpu),如“三、线程和进程”中创建多个线程的代码示例;

9、多线程的问题(加锁+释放锁)

    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()

总结:

1. 应用程序/进程/线程的关系? *****(面试题:进程/线程/协程的区别?)

2. 为什么要创建线程?

由于线程是cpu工作的最小单元,创建线程可以利用多核优势实现并行操作(Java/C#)。

注意:线程是为了工作。

3. 为什么要创建进程?

进程和进程之间做数据隔离(Java/C#)。

注意:进程是为了提供环境让线程工作。

4. Python

a. Python中存在一个GIL锁    *****

- 造成:多线程无法利用多核优势。

- 解决:开多进程处理(浪费资源)

进程和线程的使用准则:

IO密集型:多线程

计算密集型:多进程

b. 线程的创建

- Thread             *****

- MyThread

c. 其他

- join                  *****

- setDaemon      *****

- setName           *****

- threading.current_thread()  *****

d. 锁

- 获得

- 释放

操作系统/应用程序、操作中的“并发”、线程和进程,python中线程和进程(GIL锁),python线程编写+锁的更多相关文章

  1. python中socket、进程、线程、协程、池的创建方式和应用场景

    进程 场景 利用多核.高计算型的程序.启动数量有限 进程是计算机中最小的资源分配单位 进程和线程是包含关系 每个进程中都至少有一条线程 可以利用多核,数据隔离 创建 销毁 切换 时间开销都比较大 随着 ...

  2. python中多进程multiprocessing、多线程threading、线程池threadpool

    浅显点理解:进程就是一个程序,里面的线程就是用来干活的,,,进程大,线程小 一.多线程threading 简单的单线程和多线程运行:一个参数时,后面要加逗号 步骤:for循环,相当于多个线程——t=t ...

  3. Python之路,Day9, 进程、线程、协程篇

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

  4. Python学习之路--进程,线程,协程

    进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Q ...

  5. python中的进程、线程(threading、multiprocessing、Queue、subprocess)

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  6. python 学习笔记八 进程和线程 (进阶篇)

    什么是线程(thread)? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执 ...

  7. Python 中的进程、线程、协程、同步、异步、回调

    进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...

  8. Python学习笔记 - day13 - 进程与线程

    概述 我们都知道windows是支持多任务的操作系统. 什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务.打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多 ...

  9. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  10. python(40)- 进程、线程、协程及IO模型

    一.操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式:向下管理硬件,向上提供接口. 操作系统进行进程切换:1.出现IO操作:2.固定时间. 固定时间很短,人感受不到.每一个应用层运行起 ...

随机推荐

  1. Oracle undo 表空间管理 (摘DAVID)

    Oracle 的Undo有两种方式: 一是使用undo 表空间,二是使用回滚段. 我们通过 undo_management 参数来控制使用哪种方式,如果设为auto,就使用UNDO 表空间,这时必须要 ...

  2. 第四天 ThinkPHP手把手高速拼接站点(四)

    6月6日,晴天."熟梅天气豆生蛾.一见榴花感慨多. 芒种积阴凝雨润,菖蒲修剪莫蹉跎. " 九.后台编写-续-1 1.改动admin/Tpl/Login/index.html 自己改 ...

  3. 经常使用传感器协议3:CJ/T-188 冷热量表协议解析2

        本文详细阐述JY公司冷热量表(记热量)传输协议.并以此说明CJ/T-188协议在厂家详细应用时,并不一致. 本文及兴许文章将对这些不同点予以总结(文中所述协议与日志"CJ/T-188 ...

  4. Dart Essentials(读书笔记)——这本书非常大篇幅都在谈AngularDart,Zones概念没谈到

    Dart Essentials 文件夹 1 Getting Started 2 Practical Dart 3 The Power of HTML5 with Dart 4 Developing a ...

  5. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle

    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3.  ...

  6. php类库PHP QR Code 二维码

    php类库PHP QR Code 二维码 php类库PHP QR Code 二维码 php类库PHP QR CodePHP QR Code is open source (LGPL) library ...

  7. 封装ShareSDK中的分享功能封以及对类似第三方功能封装的心得【原创】

    本篇的主题有三个: 1.封装思想的介绍 2.我的封装代码 3.我在封装sharesdk(采用的是简洁版本)分享功能是碰到的问题,以及解决方法. PS:其实这个我之前封装过一次,不过最近在重构项目时发现 ...

  8. UIWebView加上safari风格前进后退按钮(转)

    今天在写程序内打开网页的功能,写工具条的时候发现系统图标里面竟然没有后退按钮,,由于我这个是静态库工程,不可能自己弄张图上去,不然使用本库的时候还得附上图片,经过一下午的搜索,终于找到个比较靠谱的,这 ...

  9. PLSQL快捷键设置

    1.在PL/SQL Developer中编写sql语句时,如果无法自动提示字段那是一件痛苦的事情,工作效率又低,在此演示下如何在PL/SQL Developer工具中自动提示字段,让开发者省时又省心, ...

  10. 大数据(4) - HDFS常用的shell操作

    注意:这次使用的是第二部分安装的集群,不是高可用集群 为了方便,开发,必须写集群脚本,试想集群的机器是100台以上,而不是3台的情况.... 集群启动脚本 vim /home/admin/tools/ ...