我有一个可能会长时间运行的程序,目前有4个进程,但可以配置更多。我已经研究了使用Python的
我的问题是:每次
按照我现在的做法,我是否已经解决了我试图避免的问题(多个打开的文件/套接字)?这种方法会失败吗?为什么会失败(我想能够告诉未来类似实现将会失败的原因)?
此外,使用“正常”(一个
如果有人能提供答案或链接帮助我,那就太好了。谢谢。
FYI:我正在Mac OS X Lion上测试,代码最终可能在Windows机器上的CentOS 6虚拟机上运行(如果有影响的话)。无论我使用什么解决方案都不需要在Windows上工作,但应该在基于Unix的系统上工作。 更新: 这个问题已经开始偏离记录特定行为的范畴,更多地涉及到Linux在进程复制期间如何处理文件描述符。我翻阅了我的一本大学教科书,发现如果从两个进程(在fork之前)以追加模式打开一个文件,则只要写入不超过实际内核缓冲区(尽管可能需要使用行缓冲),它们都能正确地向文件中写入。这会创建2个文件表条目和1个v-node表条目。然后再打开一个文件进行fork操作是不应该起作用的,但是只要像之前一样不超过内核缓冲区就可以工作(我在以前的程序中做过)。
所以,如果您想要跨平台的多进程日志记录,可以使用套接字,并在每个fork之后创建一个新的SocketHandler,以确保安全,就像Vinay在下面建议的那样(这应该适用于所有情况)。对我来说,由于我对软件运行的操作系统有很强的控制力,我认为我将使用一个全局的
只要它不产生...
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(<configuration stuff>)
if __name__ == "__main__":
main()
我的问题是:每次
os.fork()
后,我需要创建一个新的log
对象吗?现有的全局log
对象会发生什么?按照我现在的做法,我是否已经解决了我试图避免的问题(多个打开的文件/套接字)?这种方法会失败吗?为什么会失败(我想能够告诉未来类似实现将会失败的原因)?
此外,使用“正常”(一个
log=
表达式)记录到一个文件的方式会以何种方式失败?它会引发IOError/OSError吗?还是它只是没有完全将数据写入文件?如果有人能提供答案或链接帮助我,那就太好了。谢谢。
FYI:我正在Mac OS X Lion上测试,代码最终可能在Windows机器上的CentOS 6虚拟机上运行(如果有影响的话)。无论我使用什么解决方案都不需要在Windows上工作,但应该在基于Unix的系统上工作。 更新: 这个问题已经开始偏离记录特定行为的范畴,更多地涉及到Linux在进程复制期间如何处理文件描述符。我翻阅了我的一本大学教科书,发现如果从两个进程(在fork之前)以追加模式打开一个文件,则只要写入不超过实际内核缓冲区(尽管可能需要使用行缓冲),它们都能正确地向文件中写入。这会创建2个文件表条目和1个v-node表条目。然后再打开一个文件进行fork操作是不应该起作用的,但是只要像之前一样不超过内核缓冲区就可以工作(我在以前的程序中做过)。
所以,如果您想要跨平台的多进程日志记录,可以使用套接字,并在每个fork之后创建一个新的SocketHandler,以确保安全,就像Vinay在下面建议的那样(这应该适用于所有情况)。对我来说,由于我对软件运行的操作系统有很强的控制力,我认为我将使用一个全局的
log
对象和一个FileHandler(默认情况下以追加模式打开,并在大多数操作系统上进行行缓冲)。open
的文档中写道,“负缓冲意味着使用系统默认值,通常对于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(或其他人),我错了吗?请告诉我。谢谢你能提供更多的清晰度/确定性。