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中的相对导入和绝对导入
Jan 06 Python
python实现批量注册网站用户的示例
Feb 22 Python
详解Python中pandas的安装操作说明(傻瓜版)
Apr 08 Python
Python实现的对一个数进行因式分解操作示例
Jun 27 Python
python对csv文件追加写入列的方法
Aug 01 Python
Python实现滑动平均(Moving Average)的例子
Aug 24 Python
用python写测试数据文件过程解析
Sep 25 Python
Python中Flask-RESTful编写API接口(小白入门)
Dec 11 Python
Python如何用filter函数筛选数据
Mar 05 Python
基于python检查SSL证书到期情况代码实例
Apr 04 Python
python写文件时覆盖原来的实例方法
Jul 22 Python
python中remove函数的踩坑记录
Jan 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
收音机史话 - 1960年代前后的DIY
2021/03/02 无线电
php 缓存函数代码
2008/08/27 PHP
PHP 检查扩展库或函数是否可用的代码
2010/04/06 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
php将access数据库转换到mysql数据库的方法
2014/12/24 PHP
PHP处理postfix邮件内容的方法
2015/06/16 PHP
PHP 数组基本操作方法详解
2016/06/17 PHP
php加密解密字符串示例
2016/10/13 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
PHP实现通过二维数组键值获取一维键名操作示例
2019/10/11 PHP
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
2012/05/23 Javascript
基于jQuery的简单九宫格实现代码
2012/08/09 Javascript
js对象与打印对象分析比较
2013/04/23 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
JavaScript sub方法入门实例(把字符串显示为下标)
2014/10/17 Javascript
javascript 动态创建表格的2种方法总结
2015/03/04 Javascript
jQuery中extend()和fn.extend()方法详解
2015/06/03 Javascript
JavaScript实现自动消除按钮功能的方法
2015/08/05 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
Node.js的npm包管理器基础使用教程
2016/05/26 Javascript
整理关于Bootstrap表单的慕课笔记
2017/03/29 Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
2017/08/29 Javascript
vue根据进入的路由进行原路返回的方法
2018/09/26 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
2019/01/28 Javascript
JS 5种遍历对象的方式
2020/06/16 Javascript
python实现ftp客户端示例分享
2014/02/17 Python
pip命令无法使用的解决方法
2018/06/12 Python
selenium跳过webdriver检测并模拟登录淘宝
2019/06/12 Python
Python 程序员必须掌握的日志记录
2020/08/17 Python
python批量修改交换机密码的示例
2020/09/22 Python
北大青鸟学生求职信
2013/09/24 职场文书
物业管理求职自荐信
2013/09/25 职场文书
Nginx限流和黑名单配置
2022/05/20 Servers
Win11 PC上的Outlook搜索错误怎么办?
2022/07/15 数码科技