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实现的tab文件操作类分享
Nov 20 Python
讲解Python中的标识运算符
May 14 Python
python实现聊天小程序
Mar 13 Python
详解Django的CSRF认证实现
Oct 09 Python
python实现本地图片转存并重命名的示例代码
Oct 27 Python
Python使用folium excel绘制point
Jan 03 Python
python 读取dicom文件,生成info.txt和raw文件的方法
Jan 24 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
Jun 12 Python
Python将文字转成语音并读出来的实例详解
Jul 15 Python
Python3简单爬虫抓取网页图片代码实例
Aug 26 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
Aug 28 Python
如何利用pycharm进行代码更新比较
Nov 04 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
xajax写的留言本
2006/11/25 PHP
ThinkPHP使用UTFWry地址库进行IP定位实例
2014/04/01 PHP
yii2中的rules 自定义验证规则详解
2016/04/19 PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
2016/05/12 PHP
php制作基于xml的RSS订阅源功能示例
2017/02/08 PHP
PHP中trait使用方法详细介绍
2017/05/21 PHP
各种效果的jquery ui(接口)介绍
2008/09/17 Javascript
jquery attr 设定src中含有&amp;(宏)符号问题的解决方法
2011/07/26 Javascript
js创建数据共享接口——简化框架之间相互传值
2011/10/23 Javascript
js计算德州扑克牌面值的方法
2015/03/04 Javascript
使用C++为node.js写扩展模块
2015/04/22 Javascript
node.js抓取并分析网页内容有无特殊内容的js文件
2015/11/17 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
JS模拟简易滚动条效果代码(附demo源码)
2016/04/05 Javascript
IE和Firefox之间在JavaScript语法上的差异
2016/04/22 Javascript
javascript中利用柯里化函数实现bind方法【推荐】
2016/04/29 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
Vue CLI 3搭建vue+vuex最全分析(推荐)
2018/09/27 Javascript
浅析vue中的provide / inject 有什么用处
2019/11/10 Javascript
Vue项目移动端滚动穿透问题的实现
2020/05/19 Javascript
Python利用ansible分发处理任务
2015/08/04 Python
Python测试人员需要掌握的知识
2018/02/08 Python
Python基于递归算法实现的汉诺塔与Fibonacci数列示例
2018/04/18 Python
python中ASCII码字符与int之间的转换方法
2018/07/09 Python
在python中创建指定大小的多维数组方式
2019/11/28 Python
Python+OpenCV+图片旋转并用原底色填充新四角的例子
2019/12/12 Python
Python程序慢的重要原因
2020/09/04 Python
html5 canvas实现跟随鼠标旋转的箭头
2016/03/11 HTML / CSS
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
Happy Plugs官网:瑞典无线耳机品牌
2020/07/16 全球购物
计算机相关的自我评价
2014/01/15 职场文书
护士找工作求职信
2014/07/02 职场文书
2015年政风行风工作总结
2015/04/21 职场文书
毕业论文致谢怎么写
2015/05/14 职场文书
详解Node.js如何处理ES6模块
2021/05/15 Javascript