一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python使用文件鎖實現進程間同步功能【基于fcntl模塊】

Python使用文件鎖實現進程間同步功能【基于fcntl模塊】

2020-12-11 00:38Think-througher Python

這篇文章主要介紹了Python使用文件鎖實現進程間同步功能,結合實例形式分析了Python基于fcntl模塊文件鎖功能實現進程間同步的相關操作技巧,需要的朋友可以參考下

本文實例講述了Python使用文件鎖實現進程同步功能。分享給大家供大家參考,具體如下:

簡介

在實際應用中,會出現這種應用場景:希望shell下執行的腳本對某些競爭資源提供保護,避免出現沖突。本文將通過fcntl模塊的文件整體上鎖機制來實現這種進程間同步功能。

fcntl系統函數介紹

Linux系統提供了文件整體上鎖(flock)和更細粒度的記錄上鎖(fcntl)功能,底層功能均可由fcntl函數實現。

首先來了解記錄上鎖。記錄上鎖是讀寫鎖的一種擴展類型,它可用于有親緣關系或無親緣關系的進程間共享某個文件的讀與寫。被鎖住的文件通過其描述字訪問,執行上鎖操作的函數是fcntl。這種類型的鎖在內核中維護,其宿主標識為fcntl調用進程的進程ID。這意味著這些鎖用于不同進程間的上鎖,而不是同一進程內不同線程間的上鎖。

fcntl記錄上鎖即可用于讀也可用于寫,對于文件的任意字節,最多只能存在一種類型的鎖(讀鎖或寫鎖)。而且,一個給定字節可以有多個讀寫鎖,但只能有一個寫入鎖。

對于一個打開著某個文件的給定進程來說,當它關閉該文件的任何一個描述字或者終止時,與該文件關聯的所有鎖都被刪除。鎖不能通過fork由子進程繼承。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
NAME
    fcntl - manipulate file descriptor
SYNOPSIS
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, ... /* arg */ );
DESCRIPTION
    fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.
    fcntl() can take an optional third argument. Whether or not this argument is required is determined by cmd. The required argument type
    is indicated in parentheses after each cmd name (in most cases, the required type is int, and we identify the argument using the name
    arg), or void is specified if the argument is not required.
    Advisory record locking
    Linux implements traditional ("process-associated") UNIX record locks, as standardized by POSIX. For a Linux-specific alternative with
    better semantics, see the discussion of open file description locks below.
    F_SETLK, F_SETLKW, and F_GETLK are used to acquire, release, and test for the existence of record locks (also known as byte-range, file-
    segment, or file-region locks). The third argument, lock, is a pointer to a structure that has at least the following fields (in
    unspecified order).
      struct flock {
        ...
        short l_type;  /* Type of lock: F_RDLCK,
                  F_WRLCK, F_UNLCK */
        short l_whence; /* How to interpret l_start:
                  SEEK_SET, SEEK_CUR, SEEK_END */
        off_t l_start;  /* Starting offset for lock */
        off_t l_len;   /* Number of bytes to lock */
        pid_t l_pid;   /* PID of process blocking our lock
                  (set by F_GETLK and F_OFD_GETLK) */
        ...
      };

其次,文件上鎖源自Berkeley的Unix實現支持給整個文件上鎖或解鎖的文件上鎖(file locking),但沒有給文件內的字節范圍上鎖或解鎖的能力。

fcntl模塊及基于文件鎖的同步功能。

Python fcntl模塊提供了基于文件描述符的文件和I/O控制功能。它是Unix系統調用fcntl()和ioctl()的接口。因此,我們可以基于文件鎖來提供進程同步的功能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import fcntl
class Lock(object):
  def __init__(self, file_name):
    self.file_name = file_name
    self.handle = open(file_name, 'w')
  def lock(self):
    fcntl.flock(self.handle, fcntl.LOCK_EX)
  def unlock(self):
    fcntl.flock(self.handle, fcntl.LOCK_UN)
  def __del__(self):
    try:
      self.handle.close()
    except:
      pass

應用

我們做一個簡單的場景應用:需要從指定的服務器上下載軟件版本到/exports/images目錄下,因為這個腳本可以在多用戶環境執行。我們不希望下載出現沖突,并僅在該目錄下保留一份指定的軟件版本。下面是基于文件鎖的參考實現:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if __name__ == "__main__":
  parser = OptionParser()
  group = OptionGroup(parser, "FTP download tool", "Download build from ftp server")
  group.add_option("--server", type="string", help="FTP server's IP address")
  group.add_option("--username", type="string", help="User name")
  group.add_option("--password", type="string", help="User's password")
  group.add_option("--buildpath", type="string", help="Build path in the ftp server")
  group.add_option("--buildname", type="string", help="Build name to be downloaded")
  parser.add_option_group(group)
  (options, args) = parser.parse_args()
  local_dir = "/exports/images"
  lock_file = "/var/tmp/flock.txt"
  flock = Lock(lock_file)
  flock.lock()
  if os.path.isfile(os.path.join(local_dir, options.buildname)):
    log.info("build exists, nothing needs to be done")
    log.info("Download completed")
    flock.unlock()
    exit(0)
  log.info("start to download build " + options.buildname)
  t = paramiko.Transport((options.server, 22))
  t.connect(username=options.username, password=options.password)
  sftp = paramiko.SFTPClient.from_transport(t)
  sftp.get(os.path.join(options.buildpath, options.buildname),
       os.path.join(local_dir, options.buildname))
  sftp.close()
  t.close()
  log.info("Download completed")
  flock.unlock()

希望本文所述對大家Python程序設計有所幫助。

原文鏈接:http://blog.csdn.net/jinguangliu/article/details/71773784

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 娇小老少配xxxxx性视频 | 日韩欧美一区二区不卡 | 国产精品青青青高清在线观看 | 大团圆免费阅读全文 | 日本人泡妞xxxxxx69 | 69老司机亚洲精品一区 | 久久re热在线视频精69 | 交换年轻夫妇HD中文字幕 | 奇米影视在线视频 | 日本免费不卡在线一区二区三区 | 99r8这里精品热视频免费看 | 久热人人综合人人九九精品视频 | 欧美在线一二三区 | 色噜噜狠狠狠综合曰曰曰88av | 俄罗斯13一14处出血视频在线 | а天堂中文最新版在线官网视频 | 国产精品午夜剧场 | 免费黄色小说 | 大伊人青草狠狠久久 | 美女福利视频午夜在线 | 欧美整片完整片视频在线 | 日本高清中文字幕一区二区三区 | 亚洲午夜久久久久国产 | 四虎黄色影视 | 亚洲四虎永久在线播放 | 日本一道高清不卡免费 | 四虎网站 | 色综合色狠狠天天久久婷婷基地 | 精品国产成人a区在线观看 精品国产91久久久久久久 | 国产午夜一区二区在线观看 | 北岛玲在线视频 | 97se狠狠狠狠狼亚洲综合网 | 色综合久久日韩国产 | 王小军怎么了最新消息 | jux629三浦理惠子在线播放 | 红楼梦黄色小说 | 天天色天| 国产伦精品一区二区三区免费观看 | 美女视频在线观看视频 | 色综合色狠狠天天综合色hd | 办公室的秘密在线观看 |