python并发编程之多进程

一,什么是进程

1.进程:正在运行的程序、程序的运行过程,进程与操作系统密不可分,进程是操作系统最核心的概念。

    什么是进程:进程是正在进行的一个程序或任务,负责执行这个程序或任务的是CPU

2.实现多进程的并发执行:单核+多道技术

3.一个程序执行几次就是几个进程

二、并发与并行
    1.并发------是伪并行,单个CPU+多道技术就能实现并发(并行也属于并发)

 

进程在服务端与客户端架构中的应用

服务端

#! usr/bin/env python
# -*- coding: utf-8 -*-
from socket import *    #导入socket模块
from multiprocessing import Pool   #在multiprocessing模块下导入Pool模块
s=socket(AF_INET,SOCK_STREAM)    #导入socket中的端口
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)   #导入setsockopt中的端口
s.bind(('127.0.0.1',8085))   #绑定地址,设置端口号
s.listen(5)    #兼听---最多链接5个客户端

def talk(conn,addr):    #定义talk函数 传入conn与addr参数
    while True:    #通信循环发送
        try:    #异常处理
            data=conn.recv(1024)  #对象data最大限度接受1024个字节
            print(data.decode('utf-8'))
            if not data:break     #判断如果data为空,则跳出本次循环
            回答=input('请输入:')
            conn.send(回答.encode('utf-8'))   #将收到的消息以大写的方式发送给客户端
        except Exception:     #如果程序有异常那么就break掉
            break
    conn.close()    #断开连接
if __name__=='__main__':    #判断函数是否为主函数,是--main  否----name(文件名)
    p=Pool(4)     #进程池最多操作4个进程
    while True:    #连接循环
        conn,addr= s.accept()   #等待连接
        p.apply_async(talk,args=(conn,addr))  #往进程池中添加talk任务
    s.close()   #关闭服务端

客户端

#! usr/bin/env python
# -*- coding: utf-8 -*-
from socket import *    #导入socket模块
c=socket(AF_INET,SOCK_STREAM)   #导入socket模块中的端口
c.connect(('127.0.0.1',8085))  #连接地址

while True:   #  通信循环
    msg=input('请输入:').strip()    #用户认证且两边除空
    if not msg:continue        #判断msg为空时,跳出本层循环
    c.send(msg.encode('utf-8'))  #发送消息  将msg消息转换为utf-8
    data=c.recv(1024)            #收消息
    print(data.decode('utf-8'))  #将收到的消息以utf-8形式打印
c.close()   #关闭连接

回调函数

#! usr/bin/env python
# -*- coding: utf-8 -*-
from multiprocessing import Pool    #在multiprocessing包或文件中导入Pool模块
import requests   #导入requests模块
import os      #导入os模块

def get_page(url):  #定义get_page函数
    print('<%s> get [%s]' %(os.getpid(),url))   #打印要下载的那个网页
    response=requests.get(url)    #传入url请求拿到response这个对象
    return {'url':url,'text':response.text}     #返回页面
def parse_page(res):   #定义一个解析(parse_page)函数,并传入参数
    print('<%s> parse [%s]' %(os.getpid(),res['url']))     #打印每一个被解析的函数
    with open('db.txt','a') as f:   #打开db.txt文件
        parse_res='url:%s size:%s\n' %(res['url'],len(res['txt']))   #解析网页并计算网页长度
        f.write(parse_res)   #写解析的结果
        # 创建进程,并发爬取网页
if __name__ == '__main__':    #判断函数是否为主函数,是---main,否----就为文件名(name)
    p=Pool(4)     #生成一个进程池,进程池中有有四个进程
    urls=[
        'https://www.badu.com',
        'http://www.openstack.org',
        'https://www.python.org',
        'https://help.github.com/',
        'http://www.sina.com.cn/'
    ]
    # obj_l=[]   #建立一个空列表对象用于存放爬取到的网页内容
    for url in urls:    #循环遍历出每一个网站
        p.apply_async(get_page,args=(url,),callback=parse_page)  #将爬取的网页丢到进程池中,然后回调函数parse_page
        # obj=p.apply_async(get_page,args=(url,))   #将进程池中的网页赋值给obj这个对象
        # obj_l.append(obj)    #再将obj对象添加到新建的空列表中
    p.close()     #关闭进程池
    p.join()      #等待
   # print([obj.get() for obj in obj_l])    #打印遍历出来的每一个对象
    print('',os.getpid())     #最后打印’主‘

进程池

#####进程池

from multiprocessing import Pool           #在multiprocessing包/文件中导入模块Pool
import os,time,random             #导入模块
def task(n):         #定义task函数
    print('<%s> is runing' %os.getpid())        #打印正确的进程
    time.sleep(random.randint(1,3))        #随机停顿整数秒
    return n**2                #返回
if __name__=='__main__':   #判断函数是否为主函数,是---main,否----就为文件名(name)
    #print(os.cpu_count())   #查看cpu个数
    p=Pool(4)         #生成一个进程
    # for i in range(1,7):
    #     res=p.apply(task,args=(i,))       #同步运行
    #     print('本次任务的结果:%s' %res)
    obj_l=[]           #建立一个空列表用于存放进程
    for i in range(1,20):     #循环遍历
        obj=p.apply_async(task,args=(i,))           #遍历出所有进程
        obj_l.append(obj)       #将遍历的进程添加到新列表中
    p.close()   #禁止往进程池中再添加任务
    p.join()     #等待
    print('')     #打印主
    for obj in obj_l:     #循环遍历
        print(obj.get())   #打印得到的obj

回调函数

from multiprocessing import Pool    #在multiprocessing包或文件中导入Pool模块
import requests   #导入requests模块
import os      #导入os模块

def get_page(url):  #定义get_page函数
    print('<%s> get [%s]' %(os.getpid(),url))   #打印要下载的那个网页
    response=requests.get(url)    #传入url请求拿到response这个对象
    return {'url':url,'text':response.text}     #返回页面
def parse_page(res):   #定义一个解析(parse_page)函数,并传入参数
    print('<%s> parse [%s]' %(os.getpid(),res['url']))     #打印每一个被解析的函数
    with open('db.txt','a') as f:   #打开db.txt文件
        parse_res='url:%s size:%s\n' %(res['url'],len(res['txt']))   #解析网页并计算网页长度
        f.write(parse_res)   #写解析的结果
        # 创建进程,并发爬取网页
if __name__ == '__main__':    #判断函数是否为主函数,是---main,否----就为文件名(name)
    p=Pool(4)     #生成一个进程池,进程池中有有四个进程
    urls=[
        'https://www.badu.com',
        'http://www.openstack.org',
        'https://www.python.org',
        'https://help.github.com/',
        'http://www.sina.com.cn/'
    ]
    # obj_l=[]   #建立一个空列表对象用于存放爬取到的网页内容
    for url in urls:    #循环遍历出每一个网站
        p.apply_async(get_page,args=(url,),callback=parse_page)  #将爬取的网页丢到进程池中,然后回调函数parse_page
        # obj=p.apply_async(get_page,args=(url,))   #将进程池中的网页赋值给obj这个对象
        # obj_l.append(obj)    #再将obj对象添加到新建的空列表中
    p.close()     #关闭进程池
    p.join()      #等待
   # print([obj.get() for obj in obj_l])    #打印遍历出来的每一个对象
    print('',os.getpid())     #最后打印’主‘

 

    

转载于:https://www.cnblogs.com/mds---123/p/7444231.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值