python跨平台文件锁

 

 

封装了一下文件锁,方便使用。

在flask中,经常使用Flask-APScheduler进行任务调度。如果使用gunicorn来管理flask,可以启动多个flask进程。

例如:

nohup gunicorn -w 4 -b 0.0.0.0:5000 myflask:app &

根据-w 4的值,可以启动4个flask进程,每个进程拥有一个独立的内存空间,管理自己的 Flask-APScheduler;当Flask-APScheduler启动新的任务时,必然会重复启动4个相同的任务。

在同一时间内,如果希望相同内容的任务只有一个,那么,可以采用全局可见的文件锁。只有一个任务可以申请到锁,其他3个任务申请锁失败,使其自动退出,这样就保证任务的唯一性了。

python释放对象的时间,没有C++那么可控。所以,本类设计中,需要手动进行lock、unlock。即进入任务lock,执行完任务时unlock。

# coding=utf-8

'''
文件锁

'''
import atexit
import platform
import atexit
from flask_apscheduler import APScheduler

#动态载入模块
fcntl = None
msvcrt = None
bLinux = True
if platform.system() != 'Windows':
    fcntl = __import__("fcntl")
    bLinux = True
else:
    msvcrt = __import__('msvcrt')
    bLinux = False


#文件锁
class CFileLock:
    def __init__(self, filename):
        self.filename = filename + '.lock'
        self.file = None

    #文件锁
    def lock(self):
        if bLinux is True:
            self.file = open(self.filename, 'wb')
            try:
                fcntl.flock(self.file, fcntl.LOCK_EX | fcntl.LOCK_NB)
                print(self.filename, ' file_lock success ********')
            except:
                print(self.filename, ' file_lock error')
                return False
        else:
            self.file = open(self.filename, 'wb')
            try:
                msvcrt.locking(self.file.fileno(), msvcrt.LK_NBLCK, 1)
                print(self.filename, ' file_lock success ********')
            except:
                print(self.filename, ' file_lock error')
                return False

            return True

    def unlock(self):
        try:
            if bLinux is True:
                fcntl.flock(self.file, fcntl.LOCK_UN)
                self.file.close()
            else:
                self.file.seek(0)
                msvcrt.locking(self.file.fileno(), msvcrt.LK_UNLCK, 1)
            print(self.filename, ' file_unlock success')
        except:
            print('file_unlock error')

用法:

 # 任务调度,DB保活
    def aps_keep_db_alive(self):        

        my_lock = filelock.CFileLock(sys._getframe().f_code.co_name)
        if my_lock.lock() is False:
            print(tools.get_cur_time(), ' out CSchedulerMgr ... aps_keep_db_alive, lock failed')
            return

        #do something
        
        my_lock.unlock()

 

你可能感兴趣的:(python,量化交易系统)