python协程 读取文件_python 多进程和协程配合使用写入数据

一、需求分析

有一批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 多进程和协程的资料请关注脚本之家其它相关文章!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 中,可以使用 `multiprocessing` 模块来实现多进程读写文件。 以下是一个示例代码,其中有两个进程,一个进程用于写入数据到文件中,另一个进程用于读取文件中的数据: ```python import multiprocessing # 写入数据到文件的进程 def write_data(filename, data_queue): with open(filename, "w") as f: while True: data = data_queue.get() if data == "STOP": break f.write(data + "\n") # 读取数据从文件的进程 def read_data(filename, data_queue): with open(filename, "r") as f: for line in f: data_queue.put(line.strip()) if __name__ == "__main__": # 创建一个进程共享队列 data_queue = multiprocessing.Queue() # 创建写入文件的进程 write_process = multiprocessing.Process(target=write_data, args=("data.txt", data_queue)) # 创建读取文件的进程 read_process = multiprocessing.Process(target=read_data, args=("data.txt", data_queue)) # 启动进程 write_process.start() read_process.start() # 等待写入进程完成 write_process.join() # 停止读取进程 data_queue.put("STOP") ``` 在这个例子中,我们创建了一个共享队列 `data_queue`,写入进程将数据写入这个队列,读取进程从这个队列中读取数据。 需要注意的是,在写入进程中,我们需要将数据写入文件中并且添加一个换行符,而在读取进程中,我们需要使用 `strip()` 方法来去掉读取的每一行数据的换行符。此外,在写入进程完成后,我们向队列中添加一个 `STOP` 标记来停止读取进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值