【指令碼】如何確保應用程式的唯一性
簡介
相信大家在開發指令碼或者寫程式的時候 ,大多會遇到如何判斷已經有程式在執行的情況。比如設計備份binlog ,由於某個例項產生的binlog 數量大於備份的速度,在下一個時間點,會啟動一個新的程式對binlog進行備份。那我們要怎麼解決呢,本文分別從 shell和python的角度提出我的解決方法,同時也推薦《 》,這裡有比較詳細的討論。
一 shell 指令碼的解決方法
利用mkdir 的特性 建立已經存在的檔案目錄則會失敗。程式第一次執行的時候可以建立一個 /tmp/lock資料夾,標示當前已經執行一個程式,當啟動第二個程式時,mkdir /tmp/lock 便會失敗。
注意 linux中的trap命令是防止指令碼異常終止 :被kill (不是kill -9) ,crtl+c 中斷 比較詳細的資料 《Linux命令之trap - 在指令碼中處理訊號》http://codingstandards.iteye.com/blog/836588
二 python 指令碼的解決方法
網上搜尋python 鎖定檔案的時候,都會提示 fcntl 模組。Python的檔案鎖目前使用的是fcntl這個庫,它實際上為 Unix上的ioctl,flock和fcntl 函式提供了一個介面。
fcntl模組的函式flock(file_handle, operation)
其中 file_handle 表示檔案描述符,operation 指要進行的鎖操作,有如下幾種:
fcntl.LOCK_UN 解鎖:刪除floc()函式建立的鎖
fcntl.LOCK_EX 排他鎖:除加鎖程式外其他程式沒有對已加鎖檔案讀寫訪問許可權。
fcntl.LOCK_SH 共享鎖:所有程式沒有寫訪問許可權,即使是加鎖程式也沒有。所有程式有讀訪問許可權。
fcntl.LOCK_NB 非阻塞鎖: 此引數意味著函式不能獲得檔案鎖就立即返回,否則,如果使用LOCK_EX/LOCK_SH請求加鎖不成功,則當前程式會等待獲得檔案鎖。使用LOCK_NB可以在獲得這個排他鎖的情況下不阻塞該程式,LOCK_NB 也可以同LOCK_SH或LOCK_NB進行按位或(|)運算操作,比如fcnt.flock(file_handle,fcntl.LOCK_EX|fcntl.LOCK_NB),此時系統便不會阻塞當前的程式。
注意:
1. 對於檔案的f.close() 操作會使檔案鎖失效;
2. 主程式結束後檔案鎖失效;
3. flock()的LOCK_EX是"勸告鎖",系統核心不會強制檢查鎖的狀態,需要在程式碼中進行檔案操作的地方顯式檢查才能生效。
測試指令碼
指令碼中使用is_running 函式對檔案加鎖,time.sleep(10) 模擬長時間執行的程式,第一次執行lock.py 成功加鎖,在程式執行期間 再次執行lock.py ,獲取鎖時會失敗,並且及時退出程式。
測試例子:
會話一
會話二
三 小結
其實還可以有很多其他的方式 比如 最容易想到的 application_name.pid 或者ps application_name | wc -l 來判斷,不過使用ps 命令時,遇到和系統其他命令關鍵字一樣的時候 ,就會不準。中比較推薦使用pid ,各位讀者朋友也可以提出自己的見解。歡迎討論。
相信大家在開發指令碼或者寫程式的時候 ,大多會遇到如何判斷已經有程式在執行的情況。比如設計備份binlog ,由於某個例項產生的binlog 數量大於備份的速度,在下一個時間點,會啟動一個新的程式對binlog進行備份。那我們要怎麼解決呢,本文分別從 shell和python的角度提出我的解決方法,同時也推薦《 》,這裡有比較詳細的討論。
一 shell 指令碼的解決方法
利用mkdir 的特性 建立已經存在的檔案目錄則會失敗。程式第一次執行的時候可以建立一個 /tmp/lock資料夾,標示當前已經執行一個程式,當啟動第二個程式時,mkdir /tmp/lock 便會失敗。
-
#!/bin/bash
-
mkdir /tmp/lock
-
if [ $? -ne 0 ];then
-
echo "there is tr script running .. "
-
exit 1
-
fi
-
trap "rm -fr /tmp/lock " SIGINT SIGTERM
-
sleep 50
-
if [ -d /tmp/lock ];then
-
rm -fr /tmp/lock
-
echo "rm -fr /tmp/lock"
- fi
二 python 指令碼的解決方法
網上搜尋python 鎖定檔案的時候,都會提示 fcntl 模組。Python的檔案鎖目前使用的是fcntl這個庫,它實際上為 Unix上的ioctl,flock和fcntl 函式提供了一個介面。
fcntl模組的函式flock(file_handle, operation)
其中 file_handle 表示檔案描述符,operation 指要進行的鎖操作,有如下幾種:
fcntl.LOCK_UN 解鎖:刪除floc()函式建立的鎖
fcntl.LOCK_EX 排他鎖:除加鎖程式外其他程式沒有對已加鎖檔案讀寫訪問許可權。
fcntl.LOCK_SH 共享鎖:所有程式沒有寫訪問許可權,即使是加鎖程式也沒有。所有程式有讀訪問許可權。
fcntl.LOCK_NB 非阻塞鎖: 此引數意味著函式不能獲得檔案鎖就立即返回,否則,如果使用LOCK_EX/LOCK_SH請求加鎖不成功,則當前程式會等待獲得檔案鎖。使用LOCK_NB可以在獲得這個排他鎖的情況下不阻塞該程式,LOCK_NB 也可以同LOCK_SH或LOCK_NB進行按位或(|)運算操作,比如fcnt.flock(file_handle,fcntl.LOCK_EX|fcntl.LOCK_NB),此時系統便不會阻塞當前的程式。
注意:
1. 對於檔案的f.close() 操作會使檔案鎖失效;
2. 主程式結束後檔案鎖失效;
3. flock()的LOCK_EX是"勸告鎖",系統核心不會強制檢查鎖的狀態,需要在程式碼中進行檔案操作的地方顯式檢查才能生效。
測試指令碼
指令碼中使用is_running 函式對檔案加鎖,time.sleep(10) 模擬長時間執行的程式,第一次執行lock.py 成功加鎖,在程式執行期間 再次執行lock.py ,獲取鎖時會失敗,並且及時退出程式。
-
#!/usr/bin/python2.6
-
#coding:utf8
-
import time
-
import fcntl
-
import sys
-
def is_running(file):
-
lock_file=open(file,"w")
-
try:
-
fcntl.lockf(lock_file,fcntl.LOCK_EX|fcntl.LOCK_NB)
-
print "給檔案加鎖 ,請等待10s..."
-
except :
-
print '檔案加鎖,無法執行,請稍後執行。'
-
return None
-
return lock_file
-
-
if __name__ == "__main__":
-
lockfile="/tmp/rsync_is_running"
-
a=is_running(lockfile)
-
if a is None :
-
print "lock file failed , rsync is running .quit ..."
-
sys.exit(0)
-
else :
-
print "lock file successed !!! "
- time.sleep(10)
會話一
會話二
三 小結
其實還可以有很多其他的方式 比如 最容易想到的 application_name.pid 或者ps application_name | wc -l 來判斷,不過使用ps 命令時,遇到和系統其他命令關鍵字一樣的時候 ,就會不準。中比較推薦使用pid ,各位讀者朋友也可以提出自己的見解。歡迎討論。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-2110638/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 確保應用程式安全性
- CodeArts如何保證客戶程式碼和應用安全?
- PHP 互斥鎖:如何確保程式碼的執行緒安全?PHP執行緒
- 確保Web應用程式安全應該考慮哪些事項Web
- 程式碼混淆工具ipaguard:如何使用ipaguard保護和混淆iOS應用程式程式碼iOS
- 用於管理應用程式得shell指令碼指令碼
- blender python api 使用指令碼對骨骼進行重新命名(保證唯一性)PythonAPI指令碼
- 設計模式系列之單例模式(Singleton Pattern)——確保物件的唯一性設計模式單例物件
- Shell指令碼應用(三)指令碼
- AbsInt — 確保程式碼安全的靜態效能分析工具
- 雲應用程式如何加強隱私保護
- 使用shell指令碼在Linux中管理Java應用程式指令碼LinuxJava
- 從應用安全到程式碼安全 確保軟體安全不能忽視檢測API漏洞!API
- 如何改進你的指令碼程式指令碼
- 如何提升 Web 應用的程式碼質量Web
- appium 安卓應用指令碼APP安卓指令碼
- Jenkins使用指令碼一鍵拉取程式碼併發布應用Jenkins指令碼
- puppet確保程式執行
- shell指令碼中的變數及應用指令碼變數
- 使用Shell指令碼查詢程式對應的程式ID指令碼
- Shell指令碼應用兩個例子指令碼
- 如何確保TCP包的有序傳輸?TCP
- 工程化的NLP如何確保落地?
- Shell指令碼之for迴圈語句的應用指令碼
- 電信PMO如何確保成功?
- Jenkins 指令碼命令列應用總結Jenkins指令碼命令列
- 如何確保按時交付專案? 有哪些實用方法
- 如何在程式碼中應用設計模式設計模式
- 如何正確的開始用 Go 程式設計Go程式設計
- 【java】【集合】set集合、唯一性保證、Linkset、案例Java
- Shell指令碼應用 – for、while迴圈語句指令碼While
- Java 如何確保 JS 不被快取JavaJS快取
- 面對祖傳屎山程式碼應該採用的5個正確姿勢
- C++序列點解析:確保程式碼行為可控的關鍵步驟C++
- 應用程式無法啟動,因為應用程式的並行配置不正確 解決備忘並行
- 開發人員需要程式碼簽名證書來保護移動應用程式?
- Lua指令碼在Redis事務中的應用實踐指令碼Redis
- Lua 指令碼在 Redis 事務中的應用實踐指令碼Redis
- 如何確保招標過程的安全性?