python自动化21期day9

一、socketserver

import socketserver
# socketserver所启动的服务端是不能有input操作的
# server端一般都是根据client端的要求去执行固定的代码


class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        conn = self.request
        while True:
            msg = conn.recv(1024).decode("utf-8")
            address = self.client_address
            if hasattr(self, msg):
                print("%s:%s" % (address, msg))
                getattr(self, msg)()

    def ls(self):
        print("%s:in ls" % self.client_address[1])

    def du(self):
        print("%s:in du" % self.client_address[1])


my_server = socketserver.ThreadingTCPServer(("127.0.0.1", 9000), MyServer)
my_server.serve_forever()
server
#!/usr/bin/env python3
import socket
client = socket.socket()
client.connect(("127.0.0.1", 9000))
while True:
    msg = input(">>>:").encode("utf-8")
    if not msg:continue
    client.send(msg)
    if msg == "q":
        break
client.close()
client

二、进程

# 什么是进程 :运行中的程序
# 进程是操作系统中资源分配的最小单位
# 进程与进程之间都是异步的
# 开启一个进程是有时间开销的

# 启动多个进程
from multiprocessing import Process
import os
import time
import random


def func():
    time.sleep(random.randint(0,3))
    print("run",os.getpid())


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=func)
        p.start()




# 程序开始执行就会产生一个主进程
# python中可以主进程中用代码启动一个进程 —— 子进程
# 同时主进程也被称为父进程
# 父子进程之间的代码执行是异步的,各自执行自己的
# 父子进程之间的数据不可以共享
# 主进程会等待子进程结束之后再结束

from multiprocessing import Process
import os
import time
import random


def func():
    time.sleep(random.randint(0,3))
    print("run",os.getpid())


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=func)
        p.start()
    print("主进程ending")    # 开启子进程需要消耗时间,print的时间不固定
开启进程
#!/usr/bin/env python3
# join  阻塞,等待子进程执行结束,在执行主进程后面的代码
from multiprocessing import Process
import os
import time
import random


def func():
    time.sleep(random.randint(0,3))
    print("发送邮件",os.getpid())


if __name__ == '__main__':
    lst = []
    for i in range(10):
        p = Process(target=func)
        p.start()
        lst.append(p)
    for p in lst:p.join()
    print("所有已经已经发送完毕!!!")
join
#!/usr/bin/env python3
# 守护进程
# 守护进程也是一个子进程
# 当主进程的“代码”执行完毕之后自动结束的子进程叫做守护进程
from multiprocessing import Process
import time
import random
import os


def func():
    while 1:
        time.sleep(0.3)
        print("守护进程running",os.getpid())


def play():
    time.sleep(random.randint(0,3))
    print("子进程running",os.getpid())


if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True  # 把子进程设置成守护进程
    p.start()
    lst = []    # 如果有多个子进程 不能在start一个进程之后就立刻join,把所有的进程放到列表中,等待所有进程都start之后再逐一join
    for i in range(10):
        p1 = Process(target=play)
        p1.start()
        lst.append(p1)
    for p in lst:p.join()

    print("主进程ending")
守护进程
#!/usr/bin/env python3
# 示例火车票
# 问题:多个人同时购买火车票,大家都查到了1张票,进行购买的时候都对同一张
# 火车票进行操作,这样就会存在多人购买同一张火车票的问题。需要对购买操作进行加锁

from multiprocessing import Process,Lock
import time
import random
import os
import json
dbfile = "./db"


def search():
    time.sleep(random.random())
    with open(dbfile) as f:
        ret = json.load(f)
        print("%s:查到%s张票" % (os.getpid(), ret["count"]))


def buy():
    time.sleep(random.random())
    with open(dbfile) as f:
        ret = json.load(f)
    if ret["count"] > 0:
        ret["count"] -= 1
        with open(dbfile, "w") as f:
            json.dump(ret, f)
        print("\033[31;0m%s:购买1张票\033[0m" % os.getpid())


def run(lock):
    search()
    with lock:
        buy()


if __name__ == '__main__':
    lock = Lock()
    lst = []
    for i in range(10):
        p = Process(target=run, args=(lock,))
        p.start()
        lst.append(p)
    for p in lst:p.join()
    with open(dbfile, "w") as f:
        dic = {"count": 2}
        json.dump(dic,f)
进程锁
#!/usr/bin/env python3
# 信号量是控制锁的数量,信号量的本质是锁+计数器
from multiprocessing import Process,Semaphore
import time
import random


def go_ktv(user, s):
    with s:
        print("user%s 进入KTV" % user)
        time.sleep(random.randint(1, 3))
    print("-------->user%s 离开了KTV" % user)


if __name__ == '__main__':
    s = Semaphore(4)
    lst = []
    for i in range(10):
        p = Process(target=go_ktv, args=(i,s))
        p.start()
        lst.append(p)
    for p in lst:p.join()
    print("---打烊了---")
信号量
#!/usr/bin/env python3
# 事件内部内置了一个标志
# wait 方法 如果这个标志是True,那么wait == pass
# wait 方法 如果这个标志是False,那么wait就会陷入阻塞,一直阻塞到标志从False变成True

# 一个事件在创建之初 内部的标志默认是False
# False -> True  :set()
# True  -> False :clear()

# 红绿灯模型
from multiprocessing import Process, Event
import time,random


def car(e, n):
    while True:
        if not e.is_set():  # 进程刚开启,is_set()的值是False,模拟信号灯为红色
            print('\033[31m红灯亮\033[0m,car%s等着' % n)
            e.wait()    # 阻塞,等待is_set()的值变成True,模拟信号灯为绿色
            print('\033[32m车%s 看见绿灯亮了\033[0m' % n)
            time.sleep(random.randint(3, 6))
            if not e.is_set():   #如果is_set()的值是Flase,也就是红灯,仍然回到while语句开始
                continue
            print('车开远了,car', n)
            break


def traffic_lights(e, inverval):
    while True:
        time.sleep(inverval)   # 先睡3秒
        if e.is_set():         # 标志是True
            print('######', e.is_set())
            e.clear()  # ---->将is_set()的值设置为False
        else:                 # 标志是False
            e.set()    # ---->将is_set()的值设置为True
            print('***********',e.is_set())


if __name__ == '__main__':
    e = Event()   #e就是事件
    t = Process(target=traffic_lights, args=(e, 3))  # 创建一个进程控制红绿灯
    for i in range(10):
        p = Process(target=car,args=(e, i))  # 创建是个进程控制10辆车
        p.start()
    t.start()

    print('============》')



# 10个进程 模拟车 :车的行走要依靠当时的交通灯
# 交通灯是绿灯 车就走
# 交通灯是红灯 车就停 停到灯变绿
# wait 来等灯
# set clear 来控制灯
事件
#!/usr/bin/env python3
# 管道 + 锁  == 队列
# 管道也是一个可以实现进程之间通信的模型
# 但是管道没有锁,数据不安全

# 消息中间件
# memcache
# rabitmq
# kafka —— 大数据相关
# redis

# 队列抢票
from multiprocessing import Process,Queue
import os


def buy():

    try:
        ret = q.get_nowait()
        print("%s:抢到了%s" %(os.getpid(),ret))
    except:pass


if __name__ == '__main__':
    q = Queue()
    q.put("北京-许昌")
    lst = []
    for i in range(10):
        p = Process(target=buy)
        p.start()
        lst.append(p)
    for p in lst:p.join()
    print("shouqin了")
队列

三、线程

#!/usr/bin/env python3
# 什么是进程 :计算机资源分配的最小单位
# 什么是线程 :CPU调度的最小单位
# 多个线程之间的数据时共享的

# 线程和进程的关系 :每一个进程中都至少有一个线程
# python中线程的特点
"""
    GIL锁  全局解释器锁
    解释器的锅 Cpython解释器的问题
    在同一个进程中 同一个时刻 只能有一个线程被CPU执行
    导致高计算型 代码 不适合用python的多线程来解决
    用多进程或者分布式来解决高计算型代码

"""

# 启动多个线程
from threading import Thread
import time
import os
import random

n = 100


def func():
    global n
    n -= 1
    print(n)


if __name__ == '__main__':
    lst = []
    for i in range(100):
        t = Thread(target=func)
        t.start()
        lst.append(t)
    for t in lst:t.join()
    print("主进程running")
开启线程
#!/usr/bin/env python3
# 主线程结束了之后守护线程也同时结束
# 守护线程会等待主线程完全结束之后才结束
from threading import Thread
import time
import os
import random

def run():
    while 1:
        print("守护进程is running")

def func():
    time.sleep(random.randint(1,3))
    print("子线程is running")


if __name__ == '__main__':
    ts = Thread(target=run)
    ts.daemon = True
    ts.start()

    for i in range(10):
        t = Thread(target=func)
        t.start()
    print("主进程running")
守护线程
#!/usr/bin/env python3
# 一般情况下开机多进程的个数和线程的个数
"""
    cpu的个数+1  进程数
    cpu的个数*5  线程数
"""

# 开启进程线程池
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time


def func(i):
    time.sleep(1)
    print("%s thread is running" % i)


if __name__ == '__main__':
    t = ThreadPoolExecutor(5)
    for i in range(20):
       t.submit(func, i)
    t.shutdown()    # 和join用法一样
    print("done")
线程池
#!/usr/bin/env python3
# map用法

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time


def func(i):
    time.sleep(1)
    print("%s thread is running" % i)


if __name__ == '__main__':
    t = ThreadPoolExecutor(5)
    t.map(func,range(20))   # map取代了for+submit
    t.shutdown()    # 和join用法一样
    print("done")
线程池-map
#!/usr/bin/env python3
from concurrent.futures import ThreadPoolExecutor
import time
import random
# concurrent.futures callback是由子线程做的
# callback回调函数

urls=[
        'https://www.baidu.com',
        'https://www.python.org',
        'https://www.openstack.org',
        'https://help.github.com/',
        'http://www.sina.com.cn/',
        'http://www.cnblogs.com/',
        'http://www.sogou.com/',
        'http://www.sohu.com/'
    ]


def get_url(url):
    time.sleep(random.randint(1,3))
    return url


def fx_url(res):
    print(res.result())


if __name__ == '__main__':
    t = ThreadPoolExecutor(2)
    for url in urls:
        t.submit(get_url, url).add_done_callback(fx_url)
线程池-callback

四、协程

# 进程 计算机中资源分配的最小单位   开启进程数量:cpu+1
# 线程 CPU 调度最小单位             开启线程数量:cpu*5
# 协程 把一个线程拆分成几个         开启携程数量:500+

# 进程 线程 都是操作系统在调度
# 协程 是程序级别调度
# 减轻了操作系统的负担、增强了用户对程序的可控性

# 安装第三方模块gevent
# 示例1
# from gevent import monkey;monkey.patch_all()
import gevent
import time


def eat(name):
    print('%s eat 1' %name)
    gevent.sleep(2)
    print('%s eat 2' %name)


def play(name):
    print('%s play 1' %name)
    time.sleep(1)
    print('%s play 2' %name)


g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,name='egon')
g1.join()
g2.join()
# gevent.joinall([g1,g2])
print('')

# 示例2
from gevent import monkey;monkey.patch_all()
import gevent
import requests
import time

def get_page(url):
    print('GET: %s' %url)
    response=requests.get(url)
    if response.status_code == 200:
        print('%d bytes received from %s' %(len(response.text),url))


start_time=time.time()
gevent.joinall([
    gevent.spawn(get_page,'https://www.python.org/'),
    gevent.spawn(get_page,'https://www.yahoo.com/'),
    gevent.spawn(get_page,'https://github.com/'),
])
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))

猜你喜欢

转载自www.cnblogs.com/spf21/p/9175277.html