PYTHON2.day07
前情回顾
multiprocessing模块 创建进程
基本创建进程: Process(target,args,kwargs,name)
start()
join(\[timeout\])
进程对象属性:p.name p.pid p.daemon p.is_alive()
自定义进程类:1. 继承Process,重写__init__
2. 重写run方法
进程池: 大量进程事件需要较多进程处理,
此时进程池可以避免进程频繁创建销毁带来的系统消耗。
Pool() 创建进程池对象
apply\_async() 将事件使用进程池执行,async(异步)
close() 关闭进程池,不能再添加新的事件了
join() 回收进程池
map() 使用迭代对象为指定函数传参后,加入进程池
进程间通信
【1】管道 : Pipe() fd.recv() fd.send()
【2】消息队列:Queue() q.get()获取消息 q.put() 存入消息
q.full() q.empty() q.qsize() q.close()
1 import os
2 from multiprocessing import Process
3
4 filename = './he.jpg'
5
6 #获取文件大小
7 size = os.path.getsize(filename)
8
9 #复制上半部分
10 def top():
11 f = open(filename,'rb')
12 n = size // 2
13 fw = open("half_top.jpg",'wb')
14 while True:
15 if n < 1024:
16 data = f.read(n)
17 fw.write(data)
18 break
19 data = f.read(1024)
20 fw.write(data)
21 n -=1024
22 f.close()
23 fw.close()
24
25 #复制下半部分
26 def boot():
27 f = open(filename,'rb')
28 fw = open('half_bottom.jpg','wb')
29 f.seek(size//2,0)
30
31 while True:
32 data = f.read(1024)
33 if not data:
34 break
35 fw.write(data)
36 f.close()
37 fw.close()
38
39 t = Process(target = top)
40 b = Process(target = boot)
41 t.start()
42 b.start()
43 t.join()
44 b.join()
cope_file.py
************************************************************************************************************
一.进程间通信(续)
1.共享内存
【1】通信原理:在内存中开辟一块空间,进程可以写入内容和读取内容完成通信,
但是每次写入内容会覆盖之前的内容
【2】实现方法:
from multiprocessing import Value,Array
obj = Value(ctype,data)
功能:开辟共享内存
参数:ctype 表示共享内存空间类型'i'整 'f'浮点 'c'字符
data 共享内存空间初始数据
返回值:共享内存对象
obj.value 对该属性的修改或查看即对共享内存的读写
obj = Array(ctype,data)
功能:开辟共享内存空间
参数:ctype 表示共享内存数据类型
data 整数 则表示开辟空间的大小,
其他数据 开辟空间存放的初始化数据
返回值:共享内存对象
Array共享内存读写:通过遍历obj可以得到的每个值,直接可以通过索引号修改任意值。
1 from multiprocessing import Process,Value
2 import time
3 import random
4
5 #创共享内存
6 money = Value('i',5000)
7
8 #操作共享内存
9 def man():
10 for i in range(30):
11 time.sleep(0.2)
12 money.value += random.randint(1,1000)
13
14 def girl():
15 for i in range(30):
16 time.sleep(0.16)
17 money.value -= random.randint(100,900)
18
19 m = Process(target=man)
20 g = Process(target=girl)
21 m.start()
22 g.start()
23 m.join()
24 g.join()
25
26 print("一月余额:",money.value)
value.py
1 from multiprocessing import Process,Array
2 import time
3
4 #创建共享内存
5 #shm = Array('i',[1,2,3,4,5])
6
7 #创建共享内存,指定开辟空间大小
8 # shm =Array('i',6)
9
10
11 #存如字符串
12 shm = Array('c',b'Hello')
13
14
15 def fun():
16 for i in shm:
17 print(i)
18 # shm[2]=3000
19 shm[0] = b'h'
20
21 p = Process(target = fun)
22 p.start()
23 p.join()
24
25 for i in shm:
26 print(i,end=" ")
27 print(shm.value)#打印字符串
array_2.py
1 from multiprocessing import Process,Array
2 import time
3
4 #创建共享内存
5 #shm = Array('i',[1,2,3,4,5])
6
7 #创建共享内存,指定开辟空间大小
8 # shm =Array('i',6)
9
10
11 #存如字符串
12 shm = Array('c',b'Hello')
13
14
15 def fun():
16 for i in shm:
17 print(i)
18 # shm[2]=3000
19 shm[0] = b'h'
20
21 p = Process(target = fun)
22 p.start()
23 p.join()
24
25 for i in shm:
26 print(i,end=" ")
27 print(shm.value)#打印字符串
array_3.py
1 from multiprocessing import Process,Array
2 import time
3
4
5 #创建共享内存,指定开辟空间大小
6 shm =Array('i',6)
7
8
9
10 def fun():
11 for i in shm:
12 print(i)
13 shm[2]=3000
14
15
16 p = Process(target = fun)
17 p.start()
18 p.join()
19
20 for i in shm:
21 print(i,end=" ")
22 print()
Array.py
2.信号量(信号灯集)
[1]通信原理:给定一个数量对多个进程可见。多个进程都可以操作该数量增减,并根据数量决定自己的行为
[2]实现方法
from multiprocessing import Semaphore
sem = Semaphore(num)
功能:创建信号量对象
参数:信号量的初始值
返回值:信号量对象
sem.acqire() 将信号量减1 当信号量为0时阻塞
sem.release() 将信号量+1
sem.get\_value()获取信号量数量
补充:当在父进程中创建套接字,进程间通信对象,文件对象,子进程从父进程获取这些对象时,那么对对象的操作
会有属性的相互关联影响。如果在各自进程中单独创建这些对象,则各自互不影响。
1 from multiprocessing import Semaphore,Process
2 from time import sleep
3 import os
4 #创建信号量
5 sem = Semaphore(3)
6
7 def fun():
8 print("%d 想执行事件"%os.getpid())
9 #想执行事件必须得到信号资源
10 sem.acquire()
11 print("%s 抢到了一个信号量,可以执行操作"%os.getpid())
12 sleep(3)
13 print("%d执行完事件再增加信号量"%os.getgid())
14 sem.release()
15 jobs=[]
16 for i in range(5):
17 p = Process(target = fun)
18 jobs.append(p)
19 p.start()
20
21 for i in jobs:
22 i.join()
23
24 print(sem.get_value())
3sem.py
二.线程编程(Thread)
1.什么是线程
【1】线程被称为轻量级的进程
【2】线程也可以使用计算机多核资源,是多任务编程方式
【3】线程是系统分配内核的最小单元
【4】线程可以理解为进程的分支任务
2.线程特征
【1】一个进程中可以包含多个线程
【2】线程也是一个运行行为,消耗计算机资源
【3】一个进程中的所有线程共享这个进程的资源
【4】多个线程之间的运行互不影响各自运行
【5】线程的创建和销毁消耗资源远小于进程
【6】各个线程有自己的ID等特征
3.创建线程threading模块
【1】创建线程对象
from threading import Thread
t = Thread()
功能:创建线程对象
参数:target 绑定线程对象
args 元组 给线程函数位置传参
kwargs 字典 给线程函数键值传参
【2】启动线程
t.start()
【3】回收线程
t.join(\[timeout\])
4.线程对象属性:
t.name 线程名称
t.setName() 设置线程名称
t.getName() 获取线程名称
t.is\_alive() 查看线程是否在生命周期
t.daemon 设置主线程和分支线程的 关系
t.setDaemon() 设置daemon属性值
t.isDaemon() 查看daemon属性值
\*daemon为True时主线程退出分支线程也退出。
要在start前设置,通常不和join一起使用
1 import threading
2 from time import sleep
3 import os
4
5 a=1
6 #线程函数
7 def music():
8 global a
9 print("a=",a)
10 for i in range(5):
11 sleep(2)
12 print("播放鱼",os.getpid())
13 a = 10000
14
15 #创建线程对象
16 t = threading.Thread(target = music)
17 t.start()
18
19 #主线程运行任务
20 for i in range(3):
21 sleep(3)
22 print("《大哥》",os.getpid())
23 t.join()
24 print("Main thread a:",a)
thread_1.py
1 from threading import Thread
2 from time import sleep
3
4 #含有参数的线程函数
5 def fun(sec,name):
6 print("线程函数传参")
7 sleep(sec)
8 print("%s 线程执行完毕"%name)
9
10 #创建多个线程
11 threads = []
12 for i in range(5):
13 t = Thread(target = fun,args=(2,),kwargs={'name':'T%d'%i})
14 threads.append(t)
15 t.start()
16
17 for i in threads:
18 i.join()
thread_2.py
1 from threading import Thread
2 from time import sleep
3
4 def fun():
5 sleep(3)
6 print("线程属性测试")
7
8 # t = Thread(target = fun)
9 t = Thread(target = fun,name = 'Tarena')
10
11
12
13 #线程名称
14 t.setName('Tedu')#设置完会覆盖之间前的名称
15 print('Thread name:',t.name)
16 print("Thread name:",t.getName())
17
18
19 #设置daemon为True
20 t.setDaemon(True)
21 t.start()
22
23 #查看线程的生命周期
24 print("alive:",t.is_alive())
25 t.join()
thread_attr.py
1. 继承Thread类
2.重写\_\_init\_\_方法添加自己的属性,使用super加载父类属性
3.重写run方法
【2】使用方法
1.实例化对象
2.调用start自动执行run方法
3.调用join回收线程
1 from threading import Thread
2 from time import sleep,ctime
3
4 class MyThread(Thread):
5 def __init__(self,target=None,args=(),kwargs={},name='Tedu'):
6 super().__init__()
7 self.target = target
8 self.args = args
9 self.kwargs = kwargs
10 self.name = name
11
12 def run(self):
13 self.target(*self.args,**self.kwargs)
14 def player(sec,song):
15 for i in range(2):
16 print("playing %s:%s"%(song,ctime()))
17 sleep(sec)
18
19 t = MyThread(target = player,args=(3,),kwargs={'song':'凉凉'},name='happy')
20
21 t.start()
22 t.join()
mythread.py
三.线程通信
【1】通信方法:线程间使用全局变量间进行通信
【2】共享资源争夺
1.共享资源:多个进程或者线程都可以操作的资源成为公共资源,
对共享资源的操作代码段称为临界区。
2.影响:对共享资源的而无需操作可能会代来数据的混乱,或者操作错误。
此时往往需要同步互斥机制协调操作顺序。
【3】同步互斥机制
同步:同步是一种协作关系,为完成操作,多进程或者线程间形成一种协调,
按照必要的步骤有序执行操作。
互斥:是一种制约关系资源,当一个进程或者线程占有资源是会进行加锁处理,
此时其他进程线程就无法操作该资源,直到解锁后才能操作。
【4】线程同步互斥方法
1.线程Event
from threading import Event
e = Event() 创建线程event对象
e.wait(\[timeout\]) 阻塞等待e被set
e.set() 设置e,使wait结束阻塞
e.clear() 使e回到未被设置的状态
e.is\_set()查看当前e是否被设置
1 from threading import Event
2
3 #创建事件对象
4 e = Event()
5
6 e.set()#设置e
7 e.clear()#清楚set状态
8 print(e.is_set())#查看是否被设置
9 e.wait(3)#超时时间
10 print("-------------")
event_test.py
1 from threading import Thread,Event
2 from time import sleep
3
4 s = None#全局变量,用于通信
5 e = Event()
6
7 def foo():
8 sleep(0.1)
9 print("Foo 前来拜山头")
10 global s
11 s = "天王盖地虎"
12 e.set()#设置e
13
14 f = Thread(target = foo)
15 f.start()
16
17 #主线程验证口令
18 print("说对口令为自己人")
19 e.wait()#添加阻塞
20 if s == '天王盖地虎':
21 print("是自己人")
22 else:
23 print("不是自己人")
24
25 f.join()
theard_event.py
2.线程锁 Lock
from threading import Lock
lock = Lock()\#创建锁对象
lock.acqire()\#上锁 如果lock已经上锁在调用会阻塞
lock.release()\#解锁
with lock: 上锁
...
...
with代码块结束自动解锁
1 from threading import Thread,Lock
2
3 a = b = 0
4 lock = Lock()#锁对象
5 #一个线程
6 def value():
7 while True:
8 lock.acquire()
9 if a!=b:
10 print("a=%d,b=%d"%(a,b))
11 lock.release()
12
13 t = Thread(target=value)
14 t.start()
15 #另一个线程
16 while True:
17 while True:
18 with lock:
19 a +=1
20 b +=1
21
22 t.join()
theard_lock.py
作业:1.对比进程线程的特点区别
2.做单进程, 多进程, 多线程的效率测试
执行10遍 创建10个进程 创建10个线程
每个执行一遍 每个执行一遍
转载于//www.cnblogs.com/shengjia/p/10416284.html
还没有评论,来说两句吧...