如何在Python线程安全的情况下将数据写入文件?我想为每个请求安全地将一些变量保存到文件中,每隔一小时我想要进行一些分组并将其写入mysql.
在Java中,我现在将它放在一个缓存的数组中,当数组已满时将其写入文件.
我怎么能用Python做到这一点?有许多并发请求,因此它必须是线程安全的.
编辑:
我们最终使用了正常工作的日志模块.
看一下这个Queue类,它是线程安全的.
from Queue import Queue
writeQueue = Queue()
Run Code Online (Sandbox Code Playgroud)
在线程中
writeQueue.put(repr(some_object))
Run Code Online (Sandbox Code Playgroud)
然后将其转储到文件中,
outFile = open(path,'w')
while writeQueue.qsize():
outFile.write(writeQueue.get())
outFile.flush()
outFile.close()
Run Code Online (Sandbox Code Playgroud)
Queue将接受任何python对象,因此如果您尝试执行除打印到文件之外的其他操作,只需通过工作线程存储对象Queue.put.
如果需要跨脚本的多个调用拆分提交,则需要一种方法将部分构建的提交缓存到磁盘.要避免多个副本同时尝试写入文件,请使用lockfile通过pip提供的模块.我通常使用json为这些目的编码数据,它支持序列化字符串,unicode,列表,数字和dicts,并且比pickle更安全.
with lockfile.LockFile('/path/to/file.sql'):
fin=open('/path/to/file')
data=json.loads(fin.read())
data.append(newdata)
fin.close()
fout=open('/path/to/file','w')
fout.write(json.dumps(data))
fout.close()
Run Code Online (Sandbox Code Playgroud)
请注意,根据操作系统功能,锁定和解锁文件以及为每个请求重写文件所花费的时间可能比您预期的要多.如果可能的话,尝试只追加到文件,因为这会更快.此外,您可能希望使用客户端/服务器模型,其中每个"请求"都会启动一个连接到服务器进程的工作脚本,并通过网络套接字转发数据.这避免了对锁定文件的需求; 根据您正在谈论的数据量,它可能能够在服务器进程中将其全部保存在内存中,或者服务器可能需要将其序列化到磁盘并以此方式将其传递给数据库.
WSGI服务器示例:
from Queue import Queue
q=Queue()
def flushQueue():
with open(path,'w') as f:
while q.qsize():
f.write(q.get())
def application(env, start_response):
q.put("Hello World!")
if q.qsize() > 999:
flushQueue()
start_response('200 OK', [('Content-Type', 'text/html')])
return ["Hello!"]
Run Code Online (Sandbox Code Playgroud)
我们使用了日志记录模块:
import logging
logpath = "/tmp/log.log"
logger = logging.getLogger('log')
logger.setLevel(logging.INFO)
ch = logging.FileHandler(logpath)
ch.setFormatter(logging.Formatter('%(message)s'))
logger.addHandler(ch)
def application(env, start_response):
logger.info("%s %s".format("hello","world!"))
start_response('200 OK', [('Content-Type', 'text/html')])
return ["Hello!"]
Run Code Online (Sandbox Code Playgroud)