内容概要

1、进程与线程优、缺点的比较

2、适用情况

3、线程

  线程的创建

  setDaemon

  join

  event

  RLock

  队列

4、进程

  创建进程

  setDaemon

  join

  线程与进程,数据之间是否共享对比

  特殊的数据容器

  进程池

5、协程


1、进程与线程优、缺点的比较

总言:使用进程和线程的目的,提高执行效率。

进程:

  优点:能利用机器的多核性能,同时进行多个操作。

  缺点:需要耗费资源,重新开辟内存空间,耗内存。

线程:

  优点:共享内存(资源),做IO操作时,可以创造并发操作。

  缺点:抢占资源。

总结:进程并不是越多越好,最好CPU个数 = 进程个数。

     线程也并不是越多越好,应根据业务需求来确定个数,因为请求上下文切换非常耗时。

2、适用情况

IO密集型(不用CPU)   :适合多线程

计算密集型(要用CPU):适合多进程

3、线程

  (1)线程的创建(threading模块)

 import threading #导入该模块
import time def f0():
pass def f1(a1,a2):
time.sleep(1)
print(a1,a2)
f0() #创建子线程,任务为f1(),参数为args的元祖
t = threading.Thread(target=f1,args=(123,456,))
#默认setDaemon为false,主线程要等待子线程执行完毕后再结束
#设置为True后,就不等待
t.setDaemon(True)
t.start() #告诉线程我们准备好了

  (2)主线程是否等待子线程

  t.setDaemon(True/False)

  用于设置主线程执行完毕后,是否等待子线程,默认为false,要等待。

  (3)主线程是否等待某个子线程执行完毕

  t.join()  一直等待

  t.join(2)最多等待该子线程2s

  (4)线程锁RLock

  避免因并发操作而造成脏数据,线程锁能锁住全部子线程,同一时刻允许一个线程执行操作。

 #未使用线程锁时
import threading
import time gl_num = 0 def show(arg):
global gl_num
time.sleep(0.5)
gl_num +=1
print(gl_num) #开了10个线程,同时都对全局变量gl_num进行操作
for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start() print('main thread stop')

  

 #使用了线程锁时
import threading
import time gl_num = 0 lock = threading.RLock() #创建锁 def Func():
lock.acquire() #锁定
global gl_num
gl_num += 1
time.sleep(0.25)
print(gl_num)
lock.release() #释放锁 for i in range(10):
t = threading.Thread(target=Func)
t.start()
print('main thread stop')

  (5)事件(Event)

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

  event.wait()  等待绿灯开启,再继续执行

  event.clear()设为红灯

  event.set()   设为绿灯

  

 import threading

 def do(event):
print('start')
event.wait() #阻塞住,等待绿灯。event_obj.set()语句执行后,又回来继续执行下一句
print('execute') event_obj = threading.Event()
for i in range(3):
t = threading.Thread(target=do, args=(event_obj,))
t.start() event_obj.clear() #设为红灯
inp = input('input:')
if inp == 'true':
event_obj.set() #设为绿灯

执行结果:

 start
start
start
input:true
execute
execute
execute

(6)生产者消费者模型、队列(先进先出)(queue模块)

4、进程

(1)创建进程(multiprocessing模块)

 import multiprocessing
import time def f1(a1):
time.sleep(3)
print(a1) if __name__ == '__main__': #Windows上,进程语句必须放在main里面
#创建进程,任务为执行f1(),参数为11,由元祖封装
t = multiprocessing.Process(target=f1,args=(11,))
# 当daemon设为true时,主进程结束后就不再等待子进程了,默认为false要等待
t.daemon = True #所以结果没有打印出 11
t.start() t = multiprocessing.Process(target=f1,args=(22,))
t.start()
print('end')

    

(2)主进程是否等待子进程

  t.setDaemon(True/False)

  用于设置主进程执行完毕后,是否等待子进程,默认为false,要等待。

 (3)主进程是否等待某个子进程执行完毕

  t.join()  一直等待

  t.join(2)最多等待该子进程2s

  (4)线程与进程,数据之间是否共享对比

  默认每个进程之间的数据是不共享的,各做各的。

  而每个线程之间的数据是共享的。  

 #进程操作时,数据是不共享的
from multiprocessing import Process li = []
def foo(i):
li.append(i)
print('say hi',li) if __name__ == '__main__':
for i in range(10):
p = Process(target=foo,args=(i,))
p.start()

结果为:

 say hi [0]
say hi [2]
say hi [1]
say hi [3]
say hi [4]
say hi [5]
say hi [6]
say hi [7]
say hi [9]
say hi [8]

线程处理时,数据是共享的,将process改为thread,结果为:

 say hi [0]
say hi [0, 1]
say hi [0, 1, 2]
say hi [0, 1, 2, 3]
say hi [0, 1, 2, 3, 4]
say hi [0, 1, 2, 3, 4, 5]
say hi [0, 1, 2, 3, 4, 5, 6]
say hi [0, 1, 2, 3, 4, 5, 6, 7]
say hi [0, 1, 2, 3, 4, 5, 6, 7, 8]
say hi [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  (5)特殊的数据容器

  如果想要多个进程同时操作一份数据,则需要特殊的容器。

  方法一:Array数组(不推荐)

    a.创建时需要规定大小,切不能改变。

    b.内部数据必须统一为相同类型,字符串、数字等。

  方法二:manager.dict()共享数据(推荐)

    创建: m = Manager()

          dict = m.dict()

 from multiprocessing import Process,Manager

 def Foo(i,dic):
dic[i] = 100+i
print(len(dic)) # for k,v in dic.items():
# print(k,v)
if __name__ == '__main__':
manager = Manager()
dic = manager.dict()
# dic = {} #dic为普通字典时,返回值为 1 1 for i in range(2):
p = Process(target=Foo,args=(i,dic))
p.start()
p.join()

返回值为:1   2

  (6)进程池(python中已创建好) pool

  

 from multiprocessing import  Pool
import time def f1(a1):
time.sleep(1)
print(a1)
return 1000 def f2(arg):
print(arg) if __name__ == '__main__': pool = Pool(5)
# pool.apply(f1,(2,))
for i in range(10):
pool.apply_async(func=f1, args=(i,), callback=f2)#特别注意args跟的参数为元祖类型
#callback=f2表示回调函数,将f1 return的值作为参数传给f2
pool.close()
pool.join()#等待子进程执行完
pool.apply()和pool.apply_async()对比:
pool.apply() :每一个任务都是排队执行的,内部有join()方法,会等待子进程
pool.apply_async():每一个任务都是并发执行,且可以设置回调函数,内部无join()方法,
进程deamon = true,不等待子进程,要想等待子进程,需先pool.close(),再pool.join() 5、协程(高性能代名词) 线程和进程的操作时程序出发系统接口,最后的执行者是系统,协程的操作则是程序员。 存在意义:只使用一个线程,在一个线程中规定某个代码块执行顺序。
适用于: IO密集型操作 方法一:greenlet模块
    需手动切换任务(不推荐) 方法二:gevent模块(本质也是基于greenlet)
    自动切换任务,谁先回来就先处理谁(推荐)
 import gevent

 def foo():
print('')
gevent.sleep(0) #切换标志
print('') def bar():
print('')
gevent.sleep(0) #切换标志
print('') gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
结果为: 1   3   2   4  



补充知识点:http://www.cnblogs.com/wupeiqi/articles/6229292.html

python第四课——线程、进程、协程的更多相关文章

  1. python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

  2. 学到了林海峰,武沛齐讲的Day34 完 线程 进程 协程 很重要

    线程 进程 协程 很重要 ...儿子满月回家办酒,学的有点慢,坚持

  3. Python学习笔记整理总结【网络编程】【线程/进程/协程/IO多路模型/select/poll/epoll/selector】

    一.socket(单链接) 1.socket:应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socke ...

  4. 文成小盆友python-num11-(1) 线程 进程 协程

    本节主要内容 线程补充 进程 协程 一.线程补充 1.两种使用方法 这里主要涉及两种使用方法,一种为直接使用,一种为定义自己的类然后继承使用如下: 直接使用如下: import threading d ...

  5. 15.python并发编程(线程--进程--协程)

    一.进程:1.定义:进程最小的资源单位,本质就是一个程序在一个数据集上的一次动态执行(运行)的过程2.组成:进程一般由程序,数据集,进程控制三部分组成:(1)程序:用来描述进程要完成哪些功能以及如何完 ...

  6. python 线程 进程 协程 学习

    转载自大神博客:http://www.cnblogs.com/aylin/p/5601969.html 仅供学习使用···· python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和 ...

  7. python中线程 进程 协程

    多线程:#线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释器锁#只要在进行耗时的IO操作的 ...

  8. python_21_线程+进程+协程

    python_线程_进程_协程 什么是线程? -- os能够进行运算调度的最小单位,被包含在进程之中,是一串指令的集合 -- 每个线程都是独立的,可以访问同一进程下所有的资源 什么是进程? -- 每个 ...

  9. 线程&进程&协程

    线程 线程是应用程序中工作的最小单元,它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.Threading用 ...

随机推荐

  1. 201521123007《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 补充上周异常 异常堆栈追踪:获得异常发生的根源 创建自己的异常 自定义异常类不是由Java系统监测到的异常, ...

  2. 201521123017 《Java程序设计》第11周学习总结

    1. 本周学习总结 2. 书面作业 Q1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步 ...

  3. 201521123110 java课程设计

    一.需求分析 功能要求:计算机产生随机数,猜中即胜,猜不中,提示是大了还是小了,继续猜,直至猜到,给出所用时间和评语.保留用户测试成绩,做出成绩排行榜.排行榜存放到文件中. 二.本组课题及本人任务 • ...

  4. 运用GRASP原则来做uml交互类图-------pos机实例

    重要的几个GRASP原则:1.控制器模式   2.创建者模式 (原则)3.信息专家模式(原则) 4. 高内聚 低耦合   这里所说的模式并不是java中针对具体的事件的设计模式 主成功场景的几个操作: ...

  5. JSP第二篇【内置对象的介绍、4种属性范围、应用场景】

    什么是JSP内置对象 JSP引擎在调用JSP对应的jspServlet时,会传递或创建9个与web开发相关的对象供jspServlet使用.JSP技术的设计者为便于开发人员在编写JSP页面时获得这些w ...

  6. Android 之内容提供者 内容解析者 内容观察者

    contentProvider:ContentProvider在Android中的作用是对外提供数据,除了可以为所在应用提供数据外,还可以共享数据给其他应用,这是Android中解决应用之间数据共享的 ...

  7. day09<面向对象+>

    面向对象(多态的概述及其代码体现) 面向对象(多态中的成员访问特点之成员变量) 面向对象(多态中的成员访问特点之成员方法) 面向对象(多态中的成员访问特点之静态成员方法) 面向对象(超人的故事) 面向 ...

  8. Matlab入门学习(文件读写)

    一.save,load >> a=[ ]; >> b=[ ] b = >> save('b.mat','a','b');%a file named b.mat wi ...

  9. vue实例讲解之axios的使用

    本篇来讲解一下axios插件的使用,axios是用来做数据交互的插件. 这篇将基于vue实例讲解之vue-router的使用这个项目的源码进行拓展. axios的使用步骤: 1.安装axios npm ...

  10. BP算法

    1986年Rumelhart和McCelland在<并行分布式处理>中提出了BP算法,即非线性连续变换函数的多层感知器网络误差反向传播算法. 该算法的思想是:学习过程分为信号的正向传播与误 ...