python自动化_day9_进程线程协程

复习一下tcp的socket

 1 import  socket
 2 ###server
 3 sk = socket.socket()
 4 sk.bind(('127.0.0.1',8000))
 5 sk.listen()  #最大连接数
 6 
 7 conn,addr = sk.accept() #没执行一次 获取一个连接
 8 while True:
 9     conn.send(b'hellle')
10     msg = conn.recv(1024)
11     print(msg)
12 conn.close()
13 sk.close()
14 ####client
15 import socket
16 sk = socket.socket()
17 sk.connect(('127.0.0.1',8000))
18 while True:
19     msg = sk.recv(1024)
20     print(msg)
21     sk.send(b'helllo')
22 sk.close()
23 import socketserver
24 #在socket基础上实现的并发
25 class Myserver(socketserver.BaseRequestHandler):
26     def handle(self):
27         conn = self.request
28         # 并发socket这conn不需要添加其他 最好是根据cilent端做回应或者做判断。
29 myserver = socketserver.ThreadingTCPServer(('127.0.0.1',8000),Myserver)
30 myserver.serve_forever()
31 #socketserver所启动的服务端是不能有input操作
32 #server端一般都是根据cilent端的要求去执行固定的代码

并发编程:一个程序可以同时时刻做多件事情,可以解决程序中的IO操作影响程序效率的问题

#计算机 - - 穿孔纸带
#输入输出 -----大部分时间都不会占用cpu 且会降低程序的效率
#时间消耗:发送请求,从网络上获取数据 占用大部分时间 怎么才可以充分利用这一段时间。

#操作系统发展史:
# 联机批处理系统 :作业的输入/输出由CPU来处理
# 脱机批处理系统 :为克服与缓解:高速主机与慢速外设的矛盾,提高CPU的利用率,又引入了脱机批处理系统,即输入/输出脱离
# 主机控制
# 多道程序系统 :指允许多个程序同时进入内存并运行,同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统
#中的各种硬、软件资源。当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序
#多道的前提就是能够记住a程序执行到哪个地方,操作系统负责调度作业
# 多道批处理系统 :多道 成批
# 分时系统 :把时间做成切片,每个程序运行一段时间
#实时系统 :系统能够及时响应随机发生的外部事件,并在严格的时间范围内完成对该事件的处理
# 实时系统可分成两类:
#    (1)实时控制系统。当用于飞机飞行、导弹发射等的自动控制时,要求计算机能尽快处理测量系统测得的数据,及时
# 地对飞机或导弹进行控制,或将有关信息通过显示终端提供给决策人员。当用于轧钢、石化等工业生产过程控制时,也要求计
# 算机能及时处理由各类传感器送来的数据,然后控制相应的执行机构。
#    (2)实时信息处理系统。当用于预定飞机票、查询有关航班、航线、票价等事宜时,或当用于银行系统、情报检索系统
# 时,都要求计算机能对终端设备发来的服务请求及时予以正确的回答。此类对响应及时性的要求稍弱于第一类。
#   实时操作系统的主要特点:
#   (1)及时响应。每一个信息接收、分析处理和发送的过程必须在严格的时间限制内完成。
#   (2)高可靠性。需采取冗余措施,双机系统前后台工作,也包括必要的保密措施等。
# 分时——现在流行的PC,服务器都是采用这种运行模式,即把CPU的运行分成若干时间片分别处理不同、的运算请求 linux系统
# 实时——一般用于单片机上、PLC等,比如电梯的上下控制中,对于按键等动作要求进行实时处理
#通用操作系统:
#  操作系统的三种基本类型:多道批处理系统、分时系统、实时系统。
#   通用操作系统:具有多种类型操作特征的操作系统。可以同时兼有多道批处理、分时、实时处理的功能,或其中两种以上的功能。
#   例如:实时处理+批处理=实时批处理系统。首先保证优先处理实时任务,插空进行批处理作业。常把实时任务称为前台作业,
# 批作业称为后台作业。
#   再如:分时处理+批处理=分时批处理系统。即:时间要求不强的作业放入“后台”(批处理)处理,需频繁交互的作业在“前
# 台”(分时)处理,处理机优先运行“前台”作业。
#   从上世纪60年代中期,国际上开始研制一些大型的通用操作系统。这些系统试图达到功能齐全、可适应各种应用范围和操作方
# 式变化多端的环境的目标。但是,这些系统过于复杂和庞大,不仅付出了巨大的代价,且在解决其可靠性、可维护性和可理解性方面都
# 遇到很大的困难。
#   相比之下,UNIX操作系统却是一个例外。这是一个通用的多用户分时交互型的操作系统。它首先建立的是一个精干的核心,而
# 其功能却足以与许多大型的操作系统相媲美,在核心层以外,可以支持庞大的软件系统。它很快得到应用和推广,并不断完善,对现代
# 操作系统有着重大的影响。
#   至此,操作系统的基本概念、功能、基本结构和组成都已形成并渐趋完善。

#现代操作系统
#基于多道批处理系统和分时系统
#多个程序,作业在遇到IO操作的时候,操作系统会帮助你进行切换
#让CPU的利用率得到最大的提高
############################进程################################
#进程 :运行中的程序   操作系统中资源分配的最小单位
#什么是程序
#操作系统 只负责管理调度进程
#每一个运行中的程序都需要有自己的内存,资源
#都分配给进程 记录执行的状态 管理自己的内存资源

#pythoon每一个运行中的程序都是一个进程
#一个进程 就能做一件事
#如果有多个进程 -----就可以完成多件事
#启动多个进程就可以实现并发
#如果用python来开启一个进程
 1 import time
 2 import os
 3 from multiprocessing import Process
 4 def func(num):
 5     print(num,os.getpid())
 6     time.sleep(100)
 7 if __name__ == '__main__':
 8     print(os.getpid())
 9     p = Process(target=func,args=(10,)) #创造一个进程
10     p.start()  #开启一个进程
11     print(os.getpid())
#同步:先做什么后做什么
#异步:一边做什么另一边做其他的
#异步可以有效的提高程序的效率
#进程与进程之间都是异步的
#开启一个进程是有时间开销的
#子进程 :
#主进程 :运行的程序
#父进程 :
#关于print的顺序

#什么是进程 : 运行中的程序 最小的资源分配单位
#python中可以用代码启动一个进程 ---- 子进程
#程序执行就会产生一个主进程
#父子进程之间的数据不可以共享
#父子进程之间的代码执行时异步的,各自执行各自的。
#进程什么时候结束
#主进程什么时候结束,主进程会等待子进程结束之后而结束
 1 n = 100
 2 def func():
 3     global n
 4     n = 0
 5     print('-----------')
 6     time.sleep(10)
 7 # func()
 8 if __name__ == '__main__':
 9     Process(target=func).start()
10     time.sleep(1)
11     print(n)
 1 #开启多个子进程  多进程
 2 def fun(n):
 3     time.sleep(1)
 4     print('-'*n)
 5 if __name__  == '__main__':
 6     l = []
 7     for i in range(10):
 8         p = Process(target=fun, args=(i,))
 9         p.start()
10         l.append(p)
11     for i in l:i.join()
12     print('十条信息都发送完了')
13     Process(target=fun,args=(1,)).start()
14     Process(target=fun,args=(2,)).start()
15     Process(target=fun,args=(3,)).start()
16     Process(target=fun,args=(4,)).start()
17     Process(target=fun,args=(5,)).start()
18 def fun(n):
19     time.sleep(1)
20     print('-'*n)
21 if __name__  == '__main__':
22     # for i in range(10):
23     p = Process(target=fun, args=(1,))
24     p.start()
25     print('子进程开始了。')
26     p.join() #阻塞会等待子进程执行完毕之后再继续
27     print('十条信息都发送完了')

守护进程:守护进程也是一个子进程,当主进程的代码执行完毕之后自动结束的进程叫做守护进程

 1 def deamon_func():
 2     while True:
 3         print('我还活着')
 4         time.sleep(0.5)
 5 def wahaha():
 6     for i in range(10):
 7         time.sleep(1)
 8         print('---'*i)
 9 if __name__ == '__main__':
10     p1 = Process(target=wahaha)
11     p1.start()
12     p = Process(target=deamon_func)
13     p.daemon = True
14     p.start()
15     for i in range(3):
16         print(i*'*')
17         time.sleep(1)
18     p1.join()
#开启一个子进程 start
#子进程和主进程是异步的
#如果在主进程中药等待子进程结束之后在执行某段代码:join
#如果有多个子进程 不能再start一个进程之后就立刻join,把所有的start放到一个列表里,等待所有的进程都start之后再逐一join
#守护进程:当主进程的“代码”执行完毕之后自动结束的进程叫做守护进程
 1 ################################lock###################################
 2 # 多进程抢占输出资源
 3 import os
 4 import time
 5 import random
 6 from multiprocessing import Process,Lock
 7 def work(n,lock):
 8     lock.acquire()
 9     print('%s:%s is running' %(n,os.getpid()))
10     time.sleep(random.random())
11     print('%s:%s is done' %(n,os.getpid()))
12     lock.release()
13 if __name__ == '__main__':
14     lock = Lock()
15     for i in range(3):
16         p = Process(target=work,args=(i,lock))
17         p.start()
18 #牺牲效率但是保证了数据的安全
 1 ################################3购票系统######################################
 2 #文件db的内容为:{"count":1}
 3 #注意一定要用双引号,不然json无法识别
 4 #并发运行,效率高,但竞争写同一文件,数据写入错乱
 5 from multiprocessing import Process,Lock
 6 import time,json,random
 7 def search():
 8     dic=json.load(open('db'))
 9     print('\033[43m剩余票数%s\033[0m' %dic['count'])
10 
11 def get(n):
12     dic=json.load(open('db'))
13     time.sleep(0.1) #模拟读数据的网络延迟
14     if dic['count'] >0:
15         dic['count']-=1
16         time.sleep(0.2) #模拟写数据的网络延迟
17         json.dump(dic,open('db','w'))
18         print('\033[43m购票成功\033[0m')
19 
20 def task(n,lock):
21     search()
22     lock.acquire()
23     get(n)
24     lock.release()
25 
26 if __name__ == '__main__':
27     lock = Lock()
28     for i in range(10): #模拟并发100个客户端抢票
29         p=Process(target=task,args=(i,lock))
30         p.start()
 1 ####################################信号量########################################################
 2 #实际工作中很少用到
 3 # 信号量就是 锁 +  计数器
 4 from multiprocessing import Semaphore
 5 sem = Semaphore(5)
 6 sem.acquire()
 7 print(1)
 8 sem.acquire()
 9 print(2)
10 sem.acquire()
11 print(3)
12 sem.acquire()
13 print(4)
14 sem.acquire()
15 print(5)
16 sem.acquire()
17 print(6)
18 from multiprocessing import Process,Semaphore
19 import time,random
20 
21 def go_ktv(sem,user):
22     sem.acquire()
23     print('%s 占到一间ktv小屋' %user)
24     time.sleep(random.randint(0,3)) #模拟每个人在ktv中待的时间不同
25     sem.release()
26 
27 if __name__ == '__main__':
28     sem=Semaphore(4)
29     p_l=[]
30     for i in range(13):
31         p=Process(target=go_ktv,args=(sem,'user%s' %i,))
32         p.start()
33         p_l.append(p)
34 
35     for i in p_l:
36         i.join()
37     print('============》')
 1 ####################################################事件##############################
 2 #事件内部内置了一个标识符
 3 # wait 方法 如果这个标志是True 那么wait == pass
 4 # wait 方法 如果这个标志是FALSE 那么wait会阻塞 一直阻塞到标志从FALSE变成true
 5 #一个事件在创建之初,内部的标志默认是Fales
 6 # 需要执行set方法  false ---》 true
 7 # 需要执行clear方法  true ---》 false
 8 #############红绿灯模型####################
 9 from multiprocessing import Process, Event
10 import time, random
11 def car(e, n):
12     while True:
13         if not e.is_set():  # 进程刚开启,is_set()的值是Flase,模拟信号灯为红色
14             print('\033[31m红灯亮\033[0m,car%s等着' % n)
15             e.wait()    # 阻塞,等待is_set()的值变成True,模拟信号灯为绿色
16             print('\033[32m车%s 看见绿灯亮了\033[0m' % n)
17             time.sleep(random.randint(3, 6))
18             if not e.is_set():   #如果is_set()的值是Flase,也就是红灯,仍然回到while语句开始
19                 continue
20             print('车开远了,car', n)
21             break
22 def police_car(e, n):
23     while True:
24         if not e.is_set():# 进程刚开启,is_set()的值是Flase,模拟信号灯为红色
25             print('\033[31m红灯亮\033[0m,car%s等着' % n)
26             e.wait(0.1) # 阻塞,等待设置等待时间,等待0.1s之后没有等到绿灯就闯红灯走了
27             if not e.is_set():
28                 print('\033[33m红灯,警车先走\033[0m,car %s' % n)
29             else:
30                 print('\033[33;46m绿灯,警车走\033[0m,car %s' % n)
31         break
32 def traffic_lights(e, inverval):
33     while True:
34         time.sleep(inverval)
35         if e.is_set():
36             print('######', e.is_set())
37             e.clear()  # ---->将is_set()的值设置为False
38         else:
39             e.set()    # ---->将is_set()的值设置为True
40             print('***********',e.is_set())
41 if __name__ == '__main__':
42     e = Event()
43     for i in range(10):
44         p=Process(target=car,args=(e,i,))  # 创建是个进程控制10辆车
45         p.start()
46 
47     for i in range(5):
48         p = Process(target=police_car, args=(e, i,))  # 创建5个进程控制5辆警车
49         p.start()
50     t = Process(target=traffic_lights, args=(e, 10))  # 创建一个进程控制红绿灯
51     t.start()
52 
53     print('============》')
 1 ####################################队列##########################
 2 from multiprocessing import Queue,Process
 3 def func(n,q):
 4     q.put(n*n)
 5 if __name__ == '__main__':
 6     q = Queue()
 7     p = Process(target=func,args=(10,q))
 8     p.start()
 9     print(q.get())
10 #管道 + 锁 = 队列
11 #管道也是一个可以实现进城之间通信的模型
12 #管道没有锁,数据不安全
 1 ################################数据共享#####################################
 2 from multiprocessing import Manager,Process,Lock
 3 def work(d,lock):
 4     with lock: #不加锁而操作共享的数据,肯定会出现数据错乱
 5         d['count']-=1
 6 
 7 if __name__ == '__main__':
 8     lock=Lock()
 9     with Manager() as m:
10         dic=m.dict({'count':100})
11         p_l=[]
12         for i in range(100):
13             p=Process(target=work,args=(dic,lock))
14             p_l.append(p)
15             p.start()
16         for p in p_l:
17             p.join()
18         print(dic)
###################################线程########################################
#什么是进程  是计算机 资源分配的最小单位
# 什么是线程
#线程和进程的关系
    #每一个进程中都至少有一个线程,真正执行代码的
#python中线程的特点
#其他语言中线程的特点
#线程是感受不到的,只有在运行多线程服务的时候才能感受到线程的存在
#线程和进程的区别:同一个进程的每个线程之间数据共享,线程之间也是异步的。
                    #线程是轻量级的,创建一个线程的时间开销要远远的小于进程
                    #线程是cpu调度的最小单位
import os
import time
from threading import Thread
import time
def fun(n):
    time.sleep(1)
    print(os.getpid())
    print('---')
Thread(target=fun,args=(1,)).start()
print(123*'*')
print(os.getpid())
#进程里至少有一个主线程负责执行代码
#在主线程中可以再开启一个新的线程
#那么在同一个进程中就有两个线程同时在工作了
#线程才是cpu调度的最小单位
#多个线程之间的数据是共享的
n = 100
def fun(i):
    global n
    time.sleep(1)
    n -= 1
    print(os.getpid(),'%sthred'%i)
t_l = []
for i in range(100):
    t = Thread(target=fun,args=(i,))
    t.start()
    t_l.append(t)
for t in t_l:t.join()
print(n)

#GIL 锁 全局解释器锁
#使用多线程处理高计算型场景  python并不占有事
#在同一个进程中 同一时刻 只能有一个线程访问cpu
#cpu主要是用来计算的
#如果程序是高IO类型的涉及到比较多的网络请求 数据库请求 文件请求 使用多线程
#celery
#在同一个进程中 同一个时刻 只能有一个线程被CPU执行 导致高计算型代码 不适合用python多线程来解决
#用多进程或者分布式来解决 高计算型代码
 1 ##############################守护线程########################################
 2 from threading import Thread
 3 import time
 4 def foo():
 5     print(123)
 6     time.sleep(1)
 7     print("end123")
 8 
 9 def bar():
10     print(456)
11     time.sleep(3)
12     print("end456")
13 
14 t1=Thread(target=foo)
15 t2=Thread(target=bar)
16 
17 t1.daemon=True
18 t1.start()
19 t2.start()
20 print("main-------")
21 #主线程结束之后守护线程同时结束
22 #守护线程会等待主线程完全结束之后才结束
 1 #################################锁############################
 2 from threading import Thread,Lock
 3 import os,time
 4 def work():
 5     global n
 6     lock.acquire()
 7     temp = n
 8     time.sleep(0.1)
 9     n = temp-1
10     lock.release()
11     # n -= 1
12 if __name__ == '__main__':
13     lock=Lock()
14     n=100
15     l=[]
16     for i in range(100):
17         p=Thread(target=work)
18         l.append(p)
19         p.start()
20     for p in l:
21         p.join()
22 #
23 #     print(n) #结果肯定为0,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全
24 #当你的程序当中出现了赋值在计算的操作 取值计算再赋值的操作就会出现数据不安全 需要 -----锁
25 #######死锁_____递归锁#############
26 from threading import Lock as Lock
27 import time
28 mutexA=Lock()
29 mutexA.acquire()
30 mutexA.acquire()
31 print(123)
32 mutexA.release()
33 mutexA.release()
34 #普通的锁 在同一个线程中 只能acquire一次
35 #所以当acquire两次的时候就容易死出现死锁 现象
36 #出现了死锁现象可以使用递归锁解决
37 #但是本质上死锁的出现是因为逻辑错误
38 #因此我们更应该把注意力集中在解决逻辑错误
39 #而不要出现错误的时候直接使用递归锁规避
 1 ###################################进程池 线程池#################################
 2 import time
 3 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
 4 def func(num):
 5     time.sleep(1)
 6     print(num)
 7 if __name__ == '__main__':
 8     t = ThreadPoolExecutor(20)
 9     for i in range(100):
10         t.submit(func,i)
11     t.shutdown()  #相当于 join
12 ###################################线程池中map##################
13 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
14 
15 import os,time,random
16 def task(n):
17     print('%s is runing' %os.getpid())
18     time.sleep(random.randint(1,3))
19     return n**2
20 if __name__ == '__main__':
21     executor=ThreadPoolExecutor(max_workers=3)
22     # for i in range(11):
23     #     future=executor.submit(task,i)
24     executor.map(task,range(1,12)) #map取代了for+submit
25 #################################回调函数################################
26 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
27 from multiprocessing import Pool
28 import requests
29 import json
30 import os
31 
32 def get_page(url):
33     print('<进程%s> get %s' %(os.getpid(),url))
34     respone=requests.get(url)
35     if respone.status_code == 200:
36         return {'url':url,'text':respone.text}
37 
38 def parse_page(res):
39     res=res.result()
40     print('<进程%s> parse %s' %(os.getpid(),res['url']))
41     parse_res='url:<%s> size:[%s]\n' %(res['url'],len(res['text']))
42     with open('db.txt','a') as f:
43         f.write(parse_res)
44 
45 
46 if __name__ == '__main__':
47     urls=[
48         'https://www.baidu.com',
49         'https://www.python.org',
50         'https://www.openstack.org',
51         'https://help.github.com/',
52         'http://www.sina.com.cn/'
53     ]
54 
55     # p=Pool(3)
56     # for url in urls:
57     #     p.apply_async(get_page,args=(url,),callback=pasrse_page)
58     # p.close()
59     # p.join()
60 
61     p=ProcessPoolExecutor(3)
62     for url in urls:
63         p.submit(get_page,url).add_done_callback(parse_page) #parse_page拿到的是一个future对象obj,需要用obj.result()拿到结果
64 #######################add_done_callback##########################################
65 import time
66 import random
67 from concurrent.futures import ThreadPoolExecutor
68 urls=[
69         'https://www.baidu.com',
70         'https://www.python.org',
71         'https://www.openstack.org',
72         'https://help.github.com/',
73         'http://www.sina.com.cn/'
74     ]
75 def analies(content):
76     print('分析网页')
77     print(content.result())
78 def get_url(url):
79     time.sleep(random.uniform(1,3))
80     return url*10
81 t = ThreadPoolExecutor(3)
82 for url in urls:
83     t.submit(get_url,url).add_done_callback(analies)
84 ###############################gevent###########################################
85 #什么是协程
86 #进程是计算机中资源分配的最小单位
87 #线程是CPU调度的最小单位
88 #协程是把一个线程拆分成几个
89 #进程 线程 都是操作系统在调度
90 #协程是程序调度  减轻了操作系统的负担,增强了用户对程序的可控性
posted @ 2018-06-29 16:09  张腾飞♂  阅读(124)  评论(0编辑  收藏  举报