crontab中的python脚本获取同时运行的另一个进程的输入参数

2 投票
4 回答
842 浏览
提问于 2025-04-16 04:19

我在定时任务(crontab)中同时运行两个Python脚本,每30分钟执行一次,比如:

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 打印出来的进程ID(PID)并不相同。 为什么会出现这种情况,我该怎么避免呢?

附注:我怀疑问题和我使用的日志记录器有关。一个脚本能否使用另一个脚本创建的日志记录器?如果可以的话,它就会在每一行打印与第一个脚本相关的数据。 每个脚本执行的代码是一样的:

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'。虽然这很奇怪,为什么一个进程的日志记录器实例会被另一个进程获取。

4 个回答

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

如果你在每个程序的每一行前面加上程序的基本名称,你还会观察到这个问题吗?

2

一个Python程序是无法直接访问另一个Python程序中的对象,除非你特别设置了一些东西,比如使用multiprocessing模块。所以我认为这并不是你遇到的问题,尽管表面上看起来可能像是这样。

为了确认这一点,可以试着使用其他的处理方式,比如FileHandlerRotatingFileHandler,看看问题是否还会出现。如果问题不再出现,那就需要仔细检查一下RotatingSqliteHandler的逻辑了。

如果问题依然存在,并且你能写出一个小的独立脚本来重复展示这个问题,请到bugs.python.org上提交一个问题,我一定会去看看。(我负责维护Python的日志处理包。)

0

这个问题让我很困惑:又有一个新想法!随机数生成器可以用“当前系统时间”来初始化(如果电脑上没有其他随机数来源的话)。在Python 2.7中,可以通过调用time.time()来实现。关键是并不是所有系统都能提供比1秒更精确的时间。更一般来说,有可能你的x.pyy.py运行得非常接近,以至于time.time()对于这两个进程是相同的,这样random.getrandbits(50)就会产生相同的结果?这和你观察到的问题偶尔出现是相符的。

你机器上time.time()的“分辨率”是什么(不同时间之间的最小间隔)?也许这个间隔足够大,以至于两个随机数生成器偶尔会以相同的方式初始化。

撰写回答