0

我有几个 python 进程可以监视物理 IO 并对其采取行动。例如,如果电流过高,则关闭电机。他们需要让彼此知道他们为什么做了某事,所以我认为共享文件可能是一个简单的解决方案。各种进程可以写入这个文件,而其他进程需要知道它何时被写入。我已经将 ConfigObj 用于静态配置文件,所以我想尝试一下动态文件。写入不应该经常发生,可能最多每秒一次,并且通常这慢得多。我想出了这个似乎有效的例子。

import copy
import os.path
import threading
import time
from configobj import ConfigObj

class config_watcher(threading.Thread):
    def __init__(self,watched_items):
        self.watched_items = watched_items
        self.config = self.watched_items['config'] 
        super(config_watcher,self).__init__()
    def run(self):
        self.reload_config()
        while 1:
            # First look for external changes
            if self.watched_items['mtime'] <> os.path.getmtime(self.config.filename):
                print "external chage detected"
                self.reload_config()
            # Now look for external changes
            if self.watched_items['config'] <> self.watched_items['copy']: 
                print "internal chage detected"
                self.save_config()
            time.sleep(.1)
    def reload_config(self):
        try:
            self.config.reload()
        except Exception:
            pass
        self.watched_items['mtime'] = os.path.getmtime(self.config.filename)
        self.watched_items['copy'] = copy.deepcopy(self.config)
    def save_config(self):
        self.config.write()
        self.reload_config()

if __name__ == '__main__':
    from random import randint
    config_file = 'test.txt'
    openfile = open(config_file, 'w')
    openfile.write('x = 0 # comment\r\n')
    openfile.close()
    config = ConfigObj(config_file)
    watched_config = {'config':config} #Dictionary to pass to thread
    config_watcher = config_watcher(watched_config) #Start thread
    config_watcher.setDaemon(True) # and make it a daemon so we can exit on ctrl-c
    config_watcher.start()
    time.sleep(.1) # Let the daemon get going
    while 1:
        newval = randint(0,9)
        print "is:{0} was:{1}, altering dictionary".format(newval,config['x'])
        config['x'] = newval
        time.sleep(1)
        openfile = open(config.filename, 'w')
        openfile.write('x = {0} # external write\r\n'.format(randint(10,19)))
        openfile.close()
        time.sleep(1)
        print "is {1} was:{0}".format(newval,config['x'])
        time.sleep(1)

我的问题是是否有更好/更容易/更清洁的方法来做到这一点?

4

2 回答 2

2

如果您有多个进程试图监视和更新相同的文件,您的方法很容易受到竞争条件的影响。

我倾向于为此使用 SQLite,制作一个带时间戳的“日志”表来记录消息。“监控”线程可以只检查最大时间戳或整数键值。有人会说这是矫枉过正,我知道,但我敢肯定,一旦你在系统中拥有一个共享数据库,你会发现它还有其他一些巧妙的用途。

作为奖励,您可以获得可审计性;变化历史可以记录在表中。

于 2012-01-18T19:41:48.857 回答
1

对于您描述的用例,即:多进程隔离和通信,您应该认真考虑Redis作为 SQL RDBMS 的替代品。

引用 Redis Labs 首席执行官 Ofer Bengal 的话,

“Redis 是一个键值数据库和 [...] 一个数据结构引擎”

简而言之,

  • 由于其通用方法数据管理命令,它非常灵活。
  • 它支持事务。
  • 它重量轻,速度快。
  • 如有必要,您可以将其配置为只读(不在磁盘上写入)。
  • 它稳定且可用于多种计算平台。

有关 Redis 事务的更多信息,您可以查看:

于 2015-11-24T17:52:17.680 回答