python 多进程和协程配合使用写入数据


Posted in Python onOctober 30, 2020

一、需求分析

有一批key已经写入到3个txt文件中,每一个txt文件有30万行记录。
现在需要读取这些txt文件,判断key是否在数据仓库中。(redis或者mysql)

为空的记录,需要写入到日志文件中!

任务分工

1. 使用多进程技术,每一个进程读取一个txt文件

2. 使用协程技术,批量读取txt文件记录。比如一次性读取 2000条记录

注意:打开文件操作,最好在一个进程中,重复打开文件,会造成系统资源浪费!

二、完整代码

#!/usr/bin/env python3
# coding: utf-8
"""
多线程和协程配合使用示例
"""

import os
import time
from gevent import monkey;monkey.patch_all()
from gevent.pool import Pool
from functools import partial
from multiprocessing import Process

COROUTINE_NUMBER = 2000 # 协程池数量
pool = Pool(COROUTINE_NUMBER) # 使用协程池

# 模拟数据仓库,测试数据
data_dict = {"1":"x1","3":"x3","5":"x5","7":"x7","9":"x9"}

class TestProgram(object): # 测试程序
 def __init__(self):
  self.BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 项目根目录

 def write_log(self,number, content, colour='white', skip=False):
  """
  写入日志文件
  :param content: 写入内容
  :param colour: 颜色
  :param skip: 是否跳过打印时间
  :return:
  """
  # 颜色代码
  colour_dict = {
   'red': 31, # 红色
   'green': 32, # 绿色
   'yellow': 33, # 黄色
   'blue': 34, # 蓝色
   'purple_red': 35, # 紫红色
   'bluish_blue': 36, # 浅蓝色
   'white': 37, # 白色
  }
  choice = colour_dict.get(colour) # 选择颜色

  path = os.path.join(self.BASE_DIR, "output_%s.log" % number) # 日志文件
  with open(path, mode='a+', encoding='utf-8') as f:
   if skip is False: # 不跳过打印时间时
    content = time.strftime('%Y-%m-%d %H:%M:%S') + ' ' + content

   info = "\033[1;{};1m{}\033[0m".format(choice, content)
   print(info)
   f.write(content + "\n")

 def has_null(self, key, number):
  """
  输出key
  :param key: 键值
  :param number: 文件标记
  :return: bool
  """
  key = key.strip()
  if not data_dict.get(key):
   self.write_log(number,"错误,{} 记录为空".format(key),"red")
   return False

  print(key)
  return True

 def read_file(self, number):
  """
  读取文件
  :param number: 文件标记
  :return:
  """
  file_name = os.path.join(self.BASE_DIR, "data", "%s.txt" % number)
  # print(file_name)
  self.write_log(number, "开始读取文件 {}".format(file_name),"green")
  with open(file_name, encoding='utf-8') as f:
   # 使用协程池,执行任务。语法: pool.map(func,iterator)
   # partial使用偏函数传递参数
   # 注意:has_null第一个参数,必须是迭代器遍历的值
   pool.map(partial(self.has_null, number=number), f)

  self.write_log(number, "结束文件读取 {} 完成".format(file_name),"green")
  return True

 def run(self, number):
  """
  读取指定的文件,判断每一个key是否为空
  :param number:
  :return:
  """
  startime = time.time() # 开始时间

  # 清空日志
  path = os.path.join(self.BASE_DIR, "output_%s.log" % number) # 日志文件
  with open(path, mode='w') as f:
   pass

  self.read_file(number)

  endtime = time.time()
  take_time = endtime - startime

  if take_time < 1: # 判断不足1秒时
   take_time = 1 # 设置为1秒
  # 计算花费时间
  m, s = divmod(take_time, 60)
  h, m = divmod(m, 60)

  self.write_log(number, "%s.txt 花费时间 %02d:%02d:%02d" % (number,h, m, s),"green")

 def main(self):
  """
  使用多线程执行程序
  :return:
  """
  # 文件标记列表
  file_list = ["7001", "7002", "7003"]

  p_lst = [] # 线程列表
  for i in file_list:
   # self.run(i)
   p = Process(target=self.run, args=(i,)) # 子进程调用函数
   p.start() # 启动子进程
   p_lst.append(p) # 将所有进程写入列表中

  for p in p_lst: p.join() # 检测p是否结束,如果没有结束就阻塞直到结束,否则不阻塞


TestProgram().main() # 启动主程序,它会开启3个进程。

执行输出

python 多进程和协程配合使用写入数据

以上就是python 多进程和协程配合使用写入数据的详细内容,更多关于python 多进程和协程的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
详谈python http长连接客户端
Jun 12 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
Jun 27 Python
python opencv实现运动检测
Jul 10 Python
树莓派3 搭建 django 服务器的实例
Aug 29 Python
Python @property使用方法解析
Sep 17 Python
Python 读取有公式cell的结果内容实例方法
Feb 17 Python
基于python3生成标签云代码解析
Feb 18 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
python安装dlib库报错问题及解决方法
Mar 16 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
Apr 09 Python
keras分类模型中的输入数据与标签的维度实例
Jul 03 Python
Python3中对json格式数据的分析处理
Jan 28 Python
python打包生成so文件的实现
Oct 30 #Python
pytorch 移动端部署之helloworld的使用
Oct 30 #Python
把Anaconda中的环境导入到Pycharm里面的方法步骤
Oct 30 #Python
Python模拟登录和登录跳转的参考示例
Oct 30 #Python
python中watchdog文件监控与检测上传功能
Oct 30 #Python
GitHub上值得推荐的8个python 项目
Oct 30 #Python
python读取excel数据绘制简单曲线图的完整步骤记录
Oct 30 #Python
You might like
php 文件上传代码(限制jpg文件)
2010/01/05 PHP
php 安全过滤函数代码
2011/05/07 PHP
php入门学习知识点五 关于php数组的几个基本操作
2011/07/14 PHP
php文件上传 你真的掌握了吗
2016/11/28 PHP
php获取今日开始时间和结束时间的方法
2017/02/27 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
JS图片无缝滚动(简单利于使用)
2013/06/17 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
JS判断浏览器是否支持某一个CSS3属性的方法
2014/10/17 Javascript
jQuery中offset()方法用法实例
2015/01/16 Javascript
JavaScript获取各大浏览器信息图示
2015/11/20 Javascript
基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用
2016/05/12 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
详解node child_process模块学习笔记
2018/01/24 Javascript
Vue 2.5.2下axios + express 本地请求404的解决方法
2018/02/21 Javascript
解决VUEX兼容IE上的报错问题
2018/03/01 Javascript
Java设计中的Builder模式的介绍
2018/03/22 Javascript
Vue 表情包输入组件的实现代码
2019/01/21 Javascript
简单了解vue.js数组的常用操作
2019/06/17 Javascript
vue中nextTick用法实例
2019/09/11 Javascript
微信小程序实现翻牌抽奖动画
2020/09/21 Javascript
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python2和3字符编码的区别知识点整理
2019/08/08 Python
python编写一个会算账的脚本的示例代码
2020/06/02 Python
Python Selenium异常处理的实例分析
2021/02/28 Python
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
纽约香氛品牌:NEST Fragrance
2018/10/15 全球购物
Jar包的作用是什么
2014/03/30 面试题
How TDD works
2012/09/30 面试题
清洁工表扬信
2014/01/08 职场文书
金融保险专业求职信
2014/09/03 职场文书
2014年志愿者工作总结
2014/11/20 职场文书
战友聚会致辞
2015/07/28 职场文书
预备党员入党感想
2015/08/10 职场文书
php 原生分页
2021/04/01 PHP
python 安全地删除列表元素的方法
2022/03/16 Python