我每30分钟同时从crontab运行2个python脚本,例如
00,30 6-19 * * 0-5 /.../x.py site1
*/3 6-19 * * 0-5 /.../y.py site2
在开始时,两个脚本都会导入一个模块,该模块会将一些数据打印到日志中,例如
name = os.path.basename(sys.argv[0])
site = sys.argv[1]
pid = os.getpid()
偶尔(!)第二个脚本y打印到脚本x的日志输入参数: name = x和site = site1 打印PID的过程是不一样的。 为什么会这样,我怎么能避免这种情况呢?
P.S。我怀疑这个问题与我使用的记录器有关。脚本可以使用在另一个脚本中创建的记录器吗?在这种情况下,它将在每行上打印与第一个脚本相关的数据。 每个脚本执行相同的代码:
log = logging.getLogger('MyLog')
log.setLevel(logging.INFO)
dh = RotatingSqliteHandler(os.path.join(progDirs['log'],'sqlitelog'),processMeta, 5000000)
log.addHandler(dh)
记录器处理程序定义如下:
class RotatingSqliteHandler(logging.Handler):
def __init__(self, filename, progData, maxBytes=0):
logging.Handler.__init__(self)
self.user = progData['user']
self.host = progData['host']
self.progName = progData['name']
self.site = progData['site']
self.pid = random.getrandbits(50)
.....
在日志中我看到记录器在最后一行生成的进程ID对于这两个脚本是相同的。
我将尝试使用每个脚本运行唯一的记录器名称而不是“MyLog”。虽然奇怪的是可以从另一个进程获取记录器实例。
答案 0 :(得分:2)
当两个脚本“同时运行”时,它们打印的行可以混合,具体取决于操作系统如何为进程分配优先级。
您可以在日志中获得以下内容:
x.py: /tmp/x.py
…
… # Other processes logging information
…
y.py: /tmp/y.py
x.py: site1 # Not printed by y!!
x.py: PID = 123
…
… # Other processes logging information
…
y.py: site2
y.py: PID = 124
如果您按每个程序基本名称为每行添加前缀,是否仍然会发现问题?
答案 1 :(得分:2)
一个Python进程不可能从另一个Python进程访问对象,除非使用例如对此进行特定的规定。 multiprocessing
模块。所以我不相信这就是发生了什么,无论表面看起来多么像。
要确认这一点,请使用替代处理程序(例如FileHandler
或RotatingFileHandler
)来查看问题是否仍然存在。如果没有,那么你应该检查RotatingSqliteHandler
逻辑。
如果确实如此,如果您能够提出一个可重复演示问题的小型独立脚本,请将问题发布到bugs.python.org,我当然会看一下。 (我维护Python日志包。)
答案 2 :(得分:0)
这可能与以下point有任何关联吗?
getLogger()返回对具有指定名称的记录器实例的引用(如果已提供),如果不是则返回root。名称是以句点分隔的层次结构。 对具有相同名称的getLogger()的多次调用将返回对同一记录器对象的引用。
这两个脚本是否可以相互“充分”连接起来扮演一个角色?例如,如果y.py
导入x.py
,那么当您在每个x.py
和y.py
中调用logging.getLogger('myLog')
时,您将获得相同的记录器。
答案 3 :(得分:0)
这个问题让我感到困惑:这是另一个想法!随机生成器可以播种“当前系统时间”(如果计算机上不存在随机数源)。在Python 2.7中,这是通过调用time.time()
来完成的。重点是that“并非所有系统都能提供比1秒更精确的时间。”更一般地说,有时您的x.py
和y.py
有可能彼此足够接近,time.time()
对于两个进程都是相同的,以便{ {1}}两者的结果相同吗?正如你所观察到的那样,这只会出现异常出现的问题。
您计算机上random.getrandbits(50)
的“分辨率”(不同时间之间的最小间隔)是多少?也许它足够大,两个随机发生器可以用同样的方式播种。