gevent文件读写坑点

本文探讨了在使用flask和gevent框架时遇到的大文件写入阻塞问题。由于Linux文件读写操作会阻塞线程,即使在非阻塞模式下,gevent也无法切换执行其他协程。测试表明,写文件操作会阻塞协程调度,而网络IO如写Redis则能避免这种情况。因此建议避免大文件写入,改用Redis或MySQL存储数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

待优化场景和现象

项目给予flask gevent框架, 会周期性的(5秒)向文件系统写一个json文件

这个文件大小为40M

现象是,进程每次在写文件到写完文件之间,gevent不会切换执行其他协程的代码,直到文件写完毕

原理

linux对于文件的读写,都会阻塞写文件的线程(不论文件的fd被设成blocking或non-blocking)

因为对于文件来说,io一直是ready的,所以线程会一直调用write写,不像网络io一样是可以异步检测ready状态(这句话如果不正确,请大家指正)

如果项目是单线程的程序,用gevent的协程来实现并行,gevent的某个协程一旦写文件,整个进程的单线程就会被阻塞,也就不会给gevent调度协程的机会,于是,所有协程都会卡住

测试

# coding=utf-8
 
from gevent.monkey import patch_all
 
patch_all()
 
import gevent
import json
import os
import sys
import redis
 
AMOUNT = 300000
OUTPUT_FILE = 'test.json'
 
r = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True)
 
dict = {}
 
 
# 生成大json
def generate_dic
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值