Recently encountered a problem writing a Python project
There is a Python script like this:
1 Scripting Features
A Monitor the real-time traffic of the network card, if the traffic exceeds the set threshold to increase the bandwidth (purchase bandwidth packet)
The B script is placed in crontab and is executed every minute
2 Experiencing problems
In the execution of the script, if the program is not completed within a minute, it is possible that two identical code will be executed simultaneously, causing the problem is to purchase two bandwidth packets at the same time, which will result in a waste of resources.
3 Solution Ideas
A can adjust the crontab, increase the time of code Execution (temporary cure)
B locks the program, allowing only one monitoring program to run at the same time.
4 resolution Steps
Therefore, how to lock the program, but also to minimize the source code changes, is the crux of the problem, I use the Python decorator.
The idea is this:
A open a Xx.pid file and add a lock for this file
B gets the PID of the current executing program and writes to the Xx.pid file
C Execute the program, close and delete the Xx.pid file after execution finishes
5 on the Code
#!/usr/bin/python# -*- coding: utf-8 -*-import fcntlfrom functools import wrapsimport osdef singleton (pid_filename): def decorator (f): @wraps (f) def Decorated (*args, **kwargs): pid = str (Os.getpid ()) pidfile = open (pid_filename, ' A + ') try: # Create an exclusive lock and lock other processes without blocking fcntl.flock (Pidfile.fileno (), fcntl. Lock_ex | fcntl. LOCK_NB)         &NBsp; except ioerror: return Pidfile.seek (0) pidfile.truncate () # empty file pidfile.write (PID) pidfile.flush () pidfile.seek (0) ret = f (*args, **kwargs) try: pidfile.close () except ioerror, err: # Possible error ioerror: [ errno 9] bad file descriptor if err.errno != 9: return os.remove (Pid_filename) return ret Return decorated return decorator
Attention:
Fcntl is only used in Linux systems and is not available in Windows
6 Simple Use Cases
@singleton ('/tmp/add_bandwidth.pid ') def add_bandwidth (): Pass
7 Code parsing
This is used in Python's fcntl module-Python to lock the file
Simple example:
>>> import fcntl>>> f = open (' test.txt ') >>> Fcntl.flock (F.fileno (), Fcntl. LOCK_EX) #对文件加锁 >>> Fcntl.flock (F.fileno (), Fcntl. Lock_un) #对文件解锁
----------------------
Flock in the Fcntl module (FD, operation):
The parameter fd represents the file descriptor;
The parameter operation specifies the lock operation to take, which has the following values:
Operation: including:
Fcntl. Lock_un Unlocking
Fcntl. LOCK_EX Exclusive Lock
Fcntl. Lock_sh shared Lock
Fcntl. LOCK_NB non-blocking lock
Lock_sh shared Lock: All processes do not have write access, even if the lock process is not. All processes have read access rights.
LOCK_EX Exclusive Lock: Other processes other than the lock process do not have read and write access to the locked file.
LOCK_NB non-blocking lock: If this parameter is specified, the function cannot get a file lock and returns immediately, otherwise the function waits for a file lock.
LOCK_NB can perform a bitwise OR (|) operation with the Lock_sh or LOCK_NB. Fcnt.flock (F,fcntl. Lock_ex|fcntl. LOCK_NB)
Attention:
1. The close () operation of the file will invalidate the file lock;
2. Similarly, the file lock fails after the process is finished;
3. The lock_ex of Flock () is "advise lock", the system kernel does not force check the state of the lock, it needs to be explicitly checked in the code where the file operation takes effect.
For details, please see the official documentation:
Https://docs.python.org/2/library/fcntl.html#fcntl.flock
This article is from "a struggling small operation" blog, please be sure to keep this source http://yucanghai.blog.51cto.com/5260262/1733004
A useful python adorner-Lock the execution program