day11_雷神_udp、多進程等

day11

一、網絡編程

1.1 udp協議

client端python

import json
import socket
server_addr = ('127.0.0.1',9090)
sk = socket.socket(type=socket.SOCK_DGRAM)
while True:
    msg = input('>>>')
    dic = {'msg': msg, 'username': 'egon'}
    send_msg = json.dumps(dic).encode('utf-8')
    sk.sendto(send_msg, server_addr)
    msg,server_addr = sk.recvfrom(1024)
    msg_dic = json.loads(msg.decode('utf-8'))
    print('消息來自%s : %s' % (msg_dic['username'], msg_dic['msg']))
sk.close()

server端算法

import json
import socket

sk = socket.socket(type= socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9090))
while True:
# 不能先發信息
    msg,client_addr = sk.recvfrom(1024)   # UDP協議接收信息的方法
    # {'msg':消息,'username':發送消息的人}
    msg_dic = json.loads(msg.decode('utf-8'))
    print('消息來自%s : %s'%(msg_dic['username'],msg_dic['msg']))
    msg = input('>>>')
    dic = {'msg':msg,'username':'server'}
    send_msg = json.dumps(dic).encode('utf-8')
    sk.sendto(send_msg,client_addr)
sk.close()

# UDP協議
    # 無鏈接,能夠多個客戶端發送
    # 快
    # 不可靠
    # 面向數據包的傳輸 只能發短消息

1.2 socketserver

server端編程

import socketserver

class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        conn = self.request
        addr = self.client_address
        while True:
            conn.send(b'hello')
            print(conn.recv(1024),addr[1])

if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',9090),Myserver)
    server.serve_forever()

client端沒有變化json

import socket

sk = socket.socket()
sk.connect(('127.0.0.1',9090))
while True:
    print(sk.recv(1024))
    sk.send(b'bye')
sk.close()

二、併發編程

2.1 操做系統

多道操做系統: 數據隔離 資源分配安全

在一臺機器讀數據進CPU的時候
這臺機器還能同時計算另一個程序


CPU在兩個程序之間切換??
    碰見不須要CPU工做的代碼的時候
    IO操做 輸入輸出
    time.sleep() input f.read sk.accept sk.recv
    print f.write sk.send
提升了CPU的工做效率

分時系統 反而下降了效率,可是提升了用戶體驗網絡

A 3min  6min
B 24h   24h3min
 短做業優先算法

CPU工做的時間 分紅很小很小的時間片
全部的做業在操做系統的調度下輪流被CPU執行
純浪費效率

CPU個數提升session

多個程序在運行
 運行中的程序 - 進程

# 進程
# 進程是計算機中資源分配的最小單位
# PID process id 進程的id
# ppid parent porcess id 父進程

2.二、 進程的並行與併發

並行 : 並行是指二者同時執行,好比賽跑,兩我的都在不停的往前
跑;(資源夠用,好比三個線程,四核的CPU )

併發 : 併發是指資源有限的狀況下,二者交替輪流使用資源,好比一
段路(單核CPU資源)同時只能過一我的,A走一段後,讓給B,B用完繼
續給A ,交替使用,目的是提升效率。

區別:

並行是從微觀上,也就是在一個精確的時間片刻,有不一樣的程序在執
行,這就要求必須有多個處理器。
併發是從宏觀上,在一個時間段上能夠看出是同時執行的,好比一個服
務器同時處理多個session。

2.3 同步異步阻塞非阻塞

同步
作完一件事情 再作另一件事情
異步
作一件事情的時候 能夠再作另外一件事情
通常說一個程序是異步程序,表示這個程序能夠多線程併發。

阻塞
recv sleep accept input recv recvfrom
非阻塞
沒有碰見上面這些阻塞的狀況就是非阻塞

阻塞和非阻塞這兩個概念與程序(線程)等待消息通知(無所謂同步或
者異步)時的狀態有關。也就是說阻塞與非阻塞主要是程序(線程)等
待消息通知時的狀態角度來講的

三、 在python中使用多進程

仔細說來,multiprocess不是一個模塊而是python中一個操做、管理進程的包。 之因此叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的全部子模塊。因爲提供的子模塊很是多,爲了方便你們歸類記憶,我將這部分大體分爲四個部分:建立進程部分,進程同步部分,進程池部分,進程之間數據共享。多線程

multiprocessing.Process

process模塊是一個建立進程的模塊,藉助這個模塊,就能夠完成進程的建立。併發

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    print('我是子進程')

if __name__ == '__main__':   # if __name__ == '__main__': 在win上必須寫,在其餘操做系統上可不寫
    p = Process(target=f, args=('bob',))
    p.start()
    time.sleep(1)
    print('執行主進程的內容了')


# 主進程和子進程的異步 併發效果、

# 主進程會等待子進程結束以後在結束, 爲何主進程要等待子進程結束
    主進程要回收子進程的資源

進階,多個進程同時運行(注意,子進程的執行順序不是根據啓動順序決定的)app

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(1)

if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
    # [p.join() for p in p_lst]
    print('父進程在執行')

主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)

除了上面這些開啓進程的方法,還有一種以繼承Process類的形式開啓進程的方式
import os
from multiprocessing import Process

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print(os.getpid())
        print('%s 正在和女主播聊天' %self.name)

p1=MyProcess('wupeiqi')
p2=MyProcess('yuanhao')
p3=MyProcess('nezha')

p1.start() #start會自動調用run
p2.start()
# p2.run()
p3.start()


p1.join()
p2.join()
p3.join()

print('主線程')

守護進程

import os
import time
from multiprocessing import Process
def func2():
    print('func2 before', os.getpid())
    time.sleep(5)
    print('func2 after',os.getpid())

def func():
    print('in func before', os.getpid())
    time.sleep(3)
    print('in func after',os.getpid())

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True   # 將p設置爲一個守護進程
    p.start()
    p = Process(target=func2)
    p.start()
    time.sleep(1)
    print('主進程',os.getpid())
# 主進程的代碼執行完畢以後 守護進程就自動結束了  - 守護進程

一、 先把QQ這個背寫出來(多進程的普通實現)
二、 多進程的類方法實現
三、 socketserver

四、join

from multiprocessing import Process

def f(name):
    print('hello', name)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
    [p.join() for p in p_lst]
    print('父進程在執行')

類的join

from multiprocessing import Process

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print(self.name)

if __name__ == '__main__':
    p = MyProcess('houbinglei')
    p.start()
    p.join()
    print('主程序')

五、daemon

import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(2)

if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.daemon = True
        p.start()
        p_lst.append(p)
    # [p.join() for p in p_lst]
    print('父進程在執行')

六、鎖

import json
import time
from multiprocessing import Process,Lock

def search(i):
    with open('ticket_db.py') as f:
        ticket = json.load(f)
    time.sleep(0.1)
    print('%s查詢餘票 : '%i,ticket['count'])

def buy_ticket(i,lock):
    lock.acquire()
    with open('ticket_db.py') as f:
        ticket = json.load(f)
    time.sleep(0.1)
    if ticket['count'] > 0:
        ticket['count'] -= 1
        print('%s購票成功'%i)
    else:
        print('購票失敗')
    time.sleep(0.1)
    with open('ticket_db.py','w') as f:
        json.dump(ticket,f)
    lock.release()

def get(i,lock):
    search(i)
    buy_ticket(i,lock)

if __name__ == '__main__':
    lock = Lock()
    for i in range(20):
        p = Process(target=get,args=(i,lock))
        p.start()

七、 隊列

from multiprocessing import Queue,Process
# IPC  Inter-process communication
def func(q):
    print(q.get())

if __name__ == '__main__':
    q = Queue()
    p = Process(target=func,args=(q,))
    p.start()
    q.put(12345)

# 隊列
# 幫助你保證進程之間的數據安全
相關文章
相關標籤/搜索