我有一个可能长期运行的程序,目前有4个进程,但可以配置为有更多.我已经使用python 研究了来自多个进程的日志记录,logging
并且使用了此处讨论的SocketHandler方法.我没有任何问题只有一个记录器(没有套接字),但从我读到的,我被告知它最终会出乎意料地失败.据我所知,当你尝试同时写入同一个文件时会发生什么.我的代码基本上做了以下事情:
import logging log = logging.getLogger(__name__) def monitor(...): # Spawn child processes with os.fork() # os.wait() and act accordingly def main(): log_server_pid = os.fork() if log_server_pid == 0: # Create a LogRecordSocketServer (daemon) ... sys.exit(0) # Add SocketHandler to root logger ... monitor() if __name__ == "__main__": main()
所以我的问题是:我需要log
在每个之后创建一个新对象os.fork()
吗?现有的全局log
对象会发生什么?
通过按照我的方式做事,我是否能解决我想要避免的问题(多个打开的文件/套接字)?这会失败吗?它为什么会失败(我希望能够判断未来类似的实现是否会失败)?
此外,log=
从多个进程登录到一个文件的"正常"(一种表达式)方法以何种方式失败?它是否引发IOError/OSError?或者它只是没有完全写入文件的数据?
如果有人可以提供答案或链接来帮助我,那就太好了.谢谢.
仅供参考:我正在Mac OS X Lion上进行测试,代码可能最终会在Windows机器上的CentOS 6 VM上运行(如果这很重要).无论我使用什么解决方案都不需要在Windows上工作,但应该在基于Unix的系统上工作.
更新:这个问题已经开始摆脱日志记录的特定行为,而且更多的是linux在forks期间使用文件描述符做什么.我拿出了我的一本大学教科书,似乎如果你从两个进程(不是在一个分支之前)以附加模式打开一个文件,只要你的写入不超过它们,它们都能够正确地写入文件实际的内核缓冲区(虽然可能需要使用行缓冲,但仍然不确定).这将创建2个文件表条目和一个v节点表条目.打开一个文件,然后分叉不应该工作,但似乎只要你没有像以前那样超过内核缓冲区(我在之前的程序中完成).
所以我想,如果你想独立于平台的多处理记录您使用的插座,并创建一个新的SocketHandler每个叉后是安全的Vinay以下建议(应该在任何地方工作).对我而言,由于我可以很好地控制运行我的软件的操作系统,我想我将使用一个log
带有FileHandler的全局对象(默认情况下以附加模式打开,并在大多数操作系统上缓冲行).为文档open
说"A负缓冲装置使用系统的默认,这通常是行缓冲用于TTY设备和全缓冲用于其他文件.如果省略,系统默认使用".或者我可以创建自己的日志记录流以确保线路缓冲.为了清楚起见,我很满意:
# Process A a_file.write("A\n") a_file.write("A\n") # Process B a_file.write("B\n")
生产...
A\n B\n A\n
只要它不产生......
AB\n \n A\n
Vinay(或任何其他人),我有多难?让我知道.感谢您提供更多清晰/可靠性.