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字符串的常用操作方法小结
May 21 Python
Python 制作糗事百科爬虫实例
Sep 22 Python
python 链接和操作 memcache方法
Mar 04 Python
利用python批量给云主机配置安全组的方法教程
Jun 21 Python
python3 图片referer防盗链的实现方法
Mar 12 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
Jun 09 Python
Django unittest 设置跳过某些case的方法
Dec 26 Python
Python中文件的写入读取以及附加文字方法
Jan 23 Python
Python获取Redis所有Key以及内容的方法
Feb 19 Python
python 使用多线程创建一个Buffer缓存器的实现思路
Jul 02 Python
python如何写个俄罗斯方块
Nov 06 Python
Python实战之OpenCV实现猫脸检测
Jun 26 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
一个域名查询的程序
2006/10/09 PHP
PHP的面试题集
2006/11/19 PHP
php结合ajax实现赞、顶、踩功能实例
2014/05/12 PHP
分享PHP守护进程类
2015/12/30 PHP
php生成mysql的数据字典
2016/07/07 PHP
Opacity.js
2007/01/22 Javascript
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
2008/11/24 Javascript
Jquery方式获取iframe页面中的 Dom元素
2014/05/07 Javascript
angular.js指令中的controller、compile与link函数的不同之处
2017/05/10 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
2017/11/22 Javascript
解析Vue 2.5的Diff算法
2017/11/28 Javascript
vuejs项目打包之后的首屏加载优化及打包之后出现的问题
2018/04/01 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
vue+axios 前端实现的常用拦截的代码示例
2018/08/23 Javascript
使用vue cli4.x搭建vue项目的过程详解
2020/05/08 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
tornado 多进程模式解析
2018/01/15 Python
Python+Django搭建自己的blog网站
2018/03/13 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
利用nohup来开启python文件的方法
2019/01/14 Python
python中import与from方法总结(推荐)
2019/03/21 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
keras 自定义loss层+接受输入实例
2020/06/28 Python
巧克力领导品牌瑞士莲美国官网:Lindt Chocolate美国
2016/08/25 全球购物
药品营销专业毕业生自荐信
2014/07/02 职场文书
暑期培训班招生方案
2014/08/26 职场文书
庆国庆活动总结
2014/08/28 职场文书
报考公务员诚信承诺书
2014/08/29 职场文书
教师师德师风整改措施
2014/10/24 职场文书
幼儿园感谢信
2015/01/21 职场文书
挂职个人工作总结
2015/03/05 职场文书
先进教师个人主要事迹材料
2015/11/03 职场文书
小学大队委竞选口号
2015/12/25 职场文书
初任公务员培训心得体会
2016/01/08 职场文书
Python极值整数的边界探讨分析
2021/09/15 Python