码迷,mamicode.com
首页 > 系统相关 > 详细

第九篇:网络编程补充与进程

时间:2017-08-31 16:03:42      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:ase   协议   用户   while   command   缓冲   语言   mon   usr   

本篇内容

  1. udp协议套接字
  2. 开启进程的方式
  3. 多进程实现并发的套接字通信
  4. join方法
  5. 守护进程
  6. 同步锁
  7. 进程队列
  8. 生产者消费者模型
  9. 进程池
  10. paramiko模块

 

一、 udp协议套接字

1.TCP和UDP在传输层区别:
UDP是无连接不可靠的数据报协议。TCP提供面向连接的可靠字节流。

2.使用UDP常见应用:
DNS(域名系统),NFS(网络文件系统),SNMP(简单网络管理协议)。

3.代码应用:

服务端:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import socketserver
class MyUDPhandler(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request)
        self.request[1].sendto(self.request[0].upper(),self.client_address)

if __name__ == ‘__main__‘:
    s = socketserver.ThreadingUDPServer((‘127.0.0.1‘,8080),MyUDPhandler)
    s.serve_forever()

 客户端:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from socket import *

udp_client = socket(AF_INET,SOCK_DGRAM)

while True:
    msg=input(‘>>: ‘).strip()
    udp_client.sendto(msg.encode(‘utf-8‘),(‘127.0.0.1‘,8080))
    data,server_addr = udp_client.recvfrom(1024)
    print(data.decode(‘utf-8‘))

 注意:但这种方式并不能控制客户端的并发数量,并发数量达到一定数量后,服务端会down掉,解决办法后续会提供。

 

二、开启进程的方式

开启进程的方式分为两种:

(1)利用模块开启进程:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process
import time
def work(name):
    print(‘task <%s> is runing‘ %name)
    time.sleep(2)
    print(‘task <%s> is done‘ % name)

if __name__ == ‘__main__‘:
    p1 = Process(target=work,args=(‘xiaolan‘,))
    p2 = Process(target=work,args=(‘xiaohong‘,))
    p1.start()
    p2.start()
    print(‘主程序‘)

 (2)利用类开启进程:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process
import time

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

    def run(self):
        print(‘task <%s> is runing‘ % self.name)
        time.sleep(2)
        print(‘task <%s> is done‘ % self.name)

if __name__ == ‘__main__‘:
    p = MyProcess(‘xiaolan‘)
    p.start()
    print(‘主程序‘)

 

三、多进程实现并发的套接字通信

基于刚刚学习的开启进程的方式,咱们就用进程的方式来开启一个网络通信。

服务端:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process
from socket import *

s = socket(AF_INET,SOCK_STREAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind((‘127.0.0.1‘,8080))
s.listen(5)

def talK(conn,addr):
    while True:
        try:
            data=conn.recv(1024)
            if not data:break
            conn.send(data.upper())
        except Exception:
            break
    conn.close()

if __name__ == ‘__main__‘:
    while True:
        conn,addr = s.accept()
        p=Process(target=talK,args=(conn,addr))
        p.start()

    s.close()

 客户端:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from socket import *

c = socket(AF_INET,SOCK_STREAM)
c.connect((‘127.0.0.1‘,8080))

while True:
    msg = input(‘>>: ‘).strip()
    if not msg:continue
    c.send(msg.encode(‘utf-8‘))
    data = c.recv(1024)
    print(data.decode(‘utf-8‘))

c.close()

 

四、join方法

1.定义:

(1)join方法的作用是阻塞主进程(挡住,无法执行join以后的语句),专注执行多进程。

(2)多进程多join的情况下,依次执行各进程的join方法,前头一个结束了才能执行后面一个。

(3)无参数,则等待到该进程结束,才开始执行下一个进程的join。

 2.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process
import time

def work(name):
    print(‘task <%s> is runing‘ %name)
    time.sleep(3)
    print(‘task <%s> is done‘ % name)

if __name__ == ‘__main__‘:
    p1 = Process(target=work,args=(‘xiaolan‘,))
    p2 = Process(target=work,args=(‘xiaohong‘,))
    p3 = Process(target=work,args=(‘xiaolv‘,))

    p_list = [p1, p2, p3]
    for p in p_list:
        p.start()
    for p in p_list:
        p.join()
    print(‘主进程‘)

 

五、守护进程

1.定义:

(1)守护进程是主程序创建的。

(2)守护进程会在主进程代码执行结束后就终止。

(3)守护进程内无法再开启子进程,否则抛出异常:

AssertionError: daemonic processes are not allowed to have children。

2.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process
import time

def work(name):
    print(‘task <%s> is runing‘ %name)
    time.sleep(2)
    print(‘task <%s> is done‘ % name)

if __name__ == ‘__main__‘:
    p1 = Process(target=work,args=(‘xiaolan‘,))
    p1.daemon = True
    p1.start()
    print(‘主程序‘)

 

六、同步锁

1.定义:

通常被用来实现共享资源的同步访问,为每一个共享资源创建一个Lock对象当你需要访问该资源时,调用qcuqire方法来获取锁对象(如果其他线程已经获得该锁,则当前线程需等待期被释放),待资源访问完后,在调用release方法释放锁。

2.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process,Lock
import time
def work(name,mutex):
    mutex.acquire()
    print(‘task <%s> is runing‘ %name)
    time.sleep(2)
    print(‘task <%s> is done‘ % name)
    mutex.release()

if __name__ == ‘__main__‘:
    mutex = Lock()
    p1 = Process(target=work,args=(‘xiaolan‘,mutex))
    p2 = Process(target=work,args=(‘xiaohong‘,mutex))
    p1.start()
    p2.start()
    print(‘主程序‘)

 3.代码应用:

模拟抢票过程

python代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import json
import os
import time
from multiprocessing import Process,Lock

def search():
    dic = json.load(open(‘db.txt‘))
    print(‘\033[32m[%s] 看到剩余票数<%s>\033[0m‘ %(os.getpid(),dic[‘count‘]))

def get_ticket():
    dic = json.load(open(‘db.txt‘))
    time.sleep(0.5) #模拟读数据库的网络延迟
    if dic[‘count‘] > 0:
        dic[‘count‘] -= 1
        time.sleep(0.5)  # 模拟写数据库的网络延迟
        json.dump(dic,open(‘db.txt‘,‘w‘))
        print(‘\033[31m%s 购票成功\033[0m‘ %os.getpid())

def task(mutex):
    search()
    mutex.acquire()
    get_ticket()
    mutex.release()

if __name__ == ‘__main__‘:
    mutex = Lock()
    for i in range(10):
        p = Process(target=task,args=(mutex,))
        p.start()

 db.txt文件:

{"count": 0}

 4.缺点:

(1)运行效率低

(2)需要自己加锁处理,操作繁琐

 

七、进程队列

1.定义:

(1)Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。

(2)maxsize是队列中允许最大项数,省略则无大小限制。

2.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Queue

q = Queue(3)

q.put(‘first‘)
q.put(‘second‘)
q.put(‘third‘)

print(q.get())
print(q.get())
print(q.get())

 

八、生产者消费者模型

1.定义:

在工作中,大家可能会碰到这样一种情况:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。

2.优点:

(1)解耦。

(2)支持并发。

(3)支持忙闲不均。

3.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Process, JoinableQueue
import time, os

def producer(q, name):
    for i in range(3):
        time.sleep(1)
        res = ‘%s%s‘ % (name, i)
        q.put(res)
        print(‘\033[45m<%s> 生产了 [%s]\033[0m‘ % (os.getpid(), res))
    q.join()

def consumer(q):
    while True:
        res = q.get()
        time.sleep(1.5)
        print(‘\033[34m<%s> 吃了 [%s]\033[0m‘ % (os.getpid(), res))
        q.task_done()

if __name__ == ‘__main__‘:
    q = JoinableQueue()
    p1 = Process(target=producer, args=(q, ‘红烧肉‘))
    p2 = Process(target=producer, args=(q, ‘鱼香肉丝‘))
    p3 = Process(target=producer, args=(q, ‘锅包肉‘))
    c1 = Process(target=consumer, args=(q,))
    c2 = Process(target=consumer, args=(q,))
    c1.daemon = True
    c2.daemon = True
    p1.start()
    p2.start()
    p3.start()
    c1.start()
    c2.start()
    p1.join()
    print(‘主程序‘)

 

九、进程池

1.定义:

Pool可以提供指定数量的进程供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。

2.代码:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

from multiprocessing import Pool
import os
import time

def work(n):
    print(‘task <%s> is runing‘ % os.getpid())
    time.sleep(2)
    return n**2

if __name__ == ‘__main__‘:
    p = Pool(4)
    res_l = []
    for i in range(10):
        res = p.apply_async(work,args=(i,))
        res_l.append(res)
    p.close()
    p.join()

 3.进程池之回调函数:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import requests
import os,time
from multiprocessing import Pool

def get_page(url):
    print(‘<%s> get :%s‘ % (os.getpid(), url))
    respone = requests.get(url)
    if respone.status_code == 200:
        return {‘url‘: url,‘text‘: respone.text}

def parse_page(dic):
    print(‘<%s> parse :%s‘ % (os.getpid(), dic[‘url‘]))
    time.sleep(0.5)
    res = ‘url:%s size:%s\n‘ % (dic[‘url‘], len(dic[‘text‘]))
    with open(‘db.txt‘, ‘a‘) as f:
        f.write(res)

if __name__ == ‘__main__‘:
    p = Pool(4)
    urls = [
        ‘https://www.baidu.com‘,
        ‘https://www.qq.com‘,
        ‘https://www.163.com‘,
        ‘https://www.sina.com‘,
        ‘https://www.jd.com‘,
        ‘https://www.taobao.com‘,
        ‘https://www.sohu.com‘,
    ]

    for url in urls:
        p.apply_async(get_page, args=(url,), callback=parse_page)
    p.close()
    p.join()
    print(‘主进程pid:‘, os.getpid())

 

十、paramiko模块

1.定义:

paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。

由于使用的是python这样的能够跨平台运行的语言,所以所有python支持的平台,如Linux, Solaris, BSD, MacOS X, Windows等,paramiko都可以支持,因此,如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,paramiko是最佳工具之一。

2.安装:

由于paramiko是第三方模块,所以是需要我们单独安装的。

pip3 install paramiko

 3.代码:

(1)使用密码连接的方式:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=‘192.168.0.1‘, port=22, username=‘root‘, password=‘root123456‘)

stdin, stdout, stderr = ssh.exec_command(‘df -h‘)
result = stdout.read()
print(result.decode(‘utf-8‘))
ssh.close()

 (2)使用秘钥连接的方式:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘id_rsa‘)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=‘192.168.0.1‘, port=22, username=‘root‘, pkey=private_key)

stdin, stdout, stderr = ssh.exec_command(‘df‘)
result = stdout.read()
print(result.decode(‘utf-8‘))
ssh.close()

 (3)上传或下载文件:

#!/usr/binl/env python
#encoding: utf-8
#author: YangLei

import paramiko

transport = paramiko.Transport((‘192.168.0.1‘, 22))
transport.connect(username=‘root‘, password=‘root123456‘)

sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(‘test.txt‘, ‘/tmp/test.txt‘)
sftp.get(‘/tmp/test.txt‘, ‘test.txt‘)
transport.close()

 

第九篇:网络编程补充与进程

标签:ase   协议   用户   while   command   缓冲   语言   mon   usr   

原文地址:http://www.cnblogs.com/00doudou00/p/7456658.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!