目录

一、说明

二、单进程实例实现

2.1 Linux平台实现--使用标准库fcntl

2.2 通用平台实现--使用第三方库portalocker

三、单例模式实现

3.1 单例模式示例代码

3.2 确认单例模式不管实例化多少次都返回同一个对象

3.3 确认单例模式可以有多个进程实例


一、说明

之前写了“Linux shell脚本单实例模式实现”,python也是日常需要使用的,所以也想来看python中如何实现。

一方面,shell中没有类和类实例的概念,所以一般说“单实例”都是指“单进程实例”,没有设计模式中“单例”的概念;另一方面,由于单进程实例和单例都是强调“唯一一份”所以在长时间里以为他们是相同的一个东西,和shell一样笼统地称为单实例就好了。

但现在看来他们不是一回事,“单进程实例”讨论的环境是整个内存、面向的对象是文件、结果是要么干掉原来的进程新启一个进程要么结束当前的进程保留原来的进程。

“单例模式”讨论的环境是一个进程内、面向的对象是类,结果是不管你在哪、调用多少次返回的都是同一个类实例。也就是说,如果是不同进程,那么是可以返回不同的类实例的(应该说就没法返回相同的类实例)。

二、单进程实例实现

2.1 Linux平台实现--使用标准库fcntl

linux平台可以通过python标准库fcntl来实现锁

import os
import time
import fcntlclass Test():# 此函数用于获取锁def _get_lock(self):file_name = os.path.basename(__file__)# 为了统一按linux的习惯放到/var/run目录去lock_file_name = f"/var/run/{file_name}.pid"# 是读还是写还是什么模式并不重要,因为只是看能不能获取文件锁而不一定要写入内容# 但是这个一定要是成员变量self.fd而不能是局部变量fd# 因为实际发现当python发现局部变量fd不再使用时会将其回收,这就导致后边再运行时都能获取到锁self.fd = open(lock_file_name, "w")try:# #define LOCK_SH 1 /* Shared lock.  */   共享锁# #define LOCK_EX 2   /* Exclusive lock.  */ 互斥锁# #define LOCK_UN 8 /* Unlock.  */ 解锁# LOCK_NB--非阻塞模式。# 阻塞模式--获取不到锁时一直等待# 非阻塞模式--获取不到锁,直接抛出异常fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB)# 将当前进程号写入文件# 如果获取不到锁上一步就已经异常了,所以不用担心覆盖self.fd.writelines(str(os.getpid()))# 写入的数据太少,默认会先被放在缓冲区,我们强制同步写入到文件self.fd.flush()except:print(f"{file_name} have another instance running.")exit(1)def __init__(self):self._get_lock()def hello_world(self):print("hello world!")time.sleep(30)# 从观察到的现像看,占用锁的进程被关闭后,锁也就自动释放了# 也就是说,其实并不需要在最后自己主动释放锁def __del__(self):fcntl.flock(self.fd, fcntl.LOCK_UN)if __name__ == "__main__":obj = Test()obj.hello_world()

2.2 通用平台实现--使用第三方库portalocker

安装方法:pip install portalocker

pypi地址:https://pypi.org/project/portalocker/

github地址:https://github.com/WoLpH/portalocker

import os
import time
import portalockerclass Test():def _get_lock(self):file_name = os.path.basename(__file__)# linux等平台依然使用标准的/var/run,其他nt等平台使用当前目录if os.name == "posix":lock_file_name = f"/var/run/{file_name}.pid"else:lock_file_name = f"{file_name}.pid"self.fd = open(lock_file_name, "w")try:portalocker.lock(self.fd, portalocker.LOCK_EX | portalocker.LOCK_NB)# 将当前进程号写入文件# 如果获取不到锁上一步就已经异常了,所以不用担心覆盖self.fd.writelines(str(os.getpid()))# 写入的数据太少,默认会先被放在缓冲区,我们强制同步写入到文件self.fd.flush()except:print(f"{file_name} have another instance running.")exit(1)def __init__(self):self._get_lock()def hello_world(self):print("hello world!")time.sleep(30)# 和fcntl有点区别,portalocker释放锁直接有unlock()方法# 还是一样,其实并不需要在最后自己主动释放锁def __del__(self):portalocker.unlock(self.fd)if __name__ == "__main__":obj = Test()obj.hello_world()

三、单例模式实现

3.1 单例模式示例代码

import time
import threading
import datetimeclass Singleton:_instance_lock = threading.Lock()def __init__(self):passdef __new__(cls, *args, **kwargs):if not hasattr(Singleton, "_instance"):with Singleton._instance_lock:if not hasattr(Singleton, "_instance"):Singleton._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return Singleton._instancedef main_logic(self):# 打印自己及当前时间print(f"instance--{self}\n"f"now time--{datetime.datetime.now().strftime('%H:%M:%S')}")time.sleep(10)if __name__ == "__main__":obj1 = Singleton()obj2 = Singleton()obj1.main_logic()obj2.main_logic()

3.2 确认单例模式不管实例化多少次都返回同一个对象

运行代码,可以看到两个实例是一样的

3.3 确认单例模式可以有多个进程实例

我们在最开始说单进程实例和单例模式是不同层次的两个东西,不能相互代替。为了消除这个疑虑,尤其是单例模式可以代替单进程实例的疑虑,我们来做一下实验。

在相同时间段内,打开两个窗口分别运行代码,可以看到两次都成功了,即使用单例模式的代码在内存中是可以有多个进程实例的。

python 单一进程实例 实现相关推荐

  1. Python实例浅谈之五Python守护进程和脚本单例运行

    一.简介 守护进程最重要的特性是后台运行:它必须与其运行前的环境隔离开来,这些环境包括未关闭的文件描述符.控制终端.会话和进程组.工作目录以及文件创建掩码等:它可以在系统启动时从启动脚本/etc/rc ...

  2. Python守护进程和脚本单例运行

    2019独角兽企业重金招聘Python工程师标准>>> 一.简介 守护进程最重要的特性是后台运行:它必须与其运行前的环境隔离开来,这些环境包括未关闭的文件描述符.控制终端.会话和进程 ...

  3. python的进程线程和协程_python成长之路 :线程、进程和协程

    python线程 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分 ...

  4. Python多任务——进程

    进程的创建-fork 1. 进程 VS 程序 编写完毕的代码,在没有运行的时候,称之为程序 正在运行着的代码,就成为进程 进程,除了包含代码以外,还有需要运行的环境等,所以和程序是有区别的 2. fo ...

  5. Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)

    文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...

  6. Python守护进程daemon实现

    1 守护进程 1.1 守护进程 守护进程是系统中生存期较长的一种进程,常常在系统引导装入时启动,在系统关闭时终止,没有控制终端,在后台运行.守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端 ...

  7. Python之进程 3 - 进程池和multiprocess.Poll

    一.为什么要有进程池? 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗 ...

  8. [转载] Python 机器学习经典实例

    参考链接: Python中的逻辑门 内容介绍 在如今这个处处以数据驱动的世界中,机器学习正变得越来越大众化.它已经被广泛地应用于不同领域,如搜索引擎.机器人.无人驾驶汽车等.本书首先通过实用的案例介绍 ...

  9. Python之进程的玩法

    Python Process的简单教程 Python的进程只用还是很简单的,不过也有几点与其他语言不一样.这里,做一个总结类型的笔记. 第一篇,只是简单介绍使用方法,不会详解进程间的通信 一. 简单的 ...

最新文章

  1. python安装venv_Python创建virtualenv(虚拟环境)方法及安装Ubuntu
  2. 在实际项目中如何应用门面模式(Facade)
  3. java算法实验标尺问题_在codeigniter项目中使用标尺库
  4. 智能指针(一):STL auto_ptr实现原理
  5. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_06-新增页面-前端-新增页面...
  6. 用python编写一个点餐程序_用python写一个 点餐代码--急急急 !!! 希望高人帮忙!...
  7. (原创)windows10cmd装逼命令
  8. 刘宝瑞相声《珍珠翡翠白玉汤》台词
  9. 华为解锁密码忘了怎么办用计算机,不记得手机锁屏密码怎么办_华为手机密码忘了的解决方法-系统城...
  10. 无法打开JFrame窗口
  11. mini2440LED驱动程序开发
  12. cad画不规则实体_cad画不规则曲线的方法步骤图
  13. PC 版微信多开防撤回软件
  14. turf.js实现行政区(多边形)图形合并边界提取,掩膜等效果
  15. 如何一小时爬取百万知乎用户信息,并做简单的可视化分析?
  16. HCIA-H12-811(1-50)
  17. 9月英语——Power English
  18. eksctl 部署AWS EKS
  19. QQ2009 Preview 下载 图片大赏+简单评测
  20. paypal、gspay、ECPSS、IPS、首信易、95epay外贸收款方式对比 网络摘录

热门文章

  1. 写好python的代码怎么放在spark上跑_Spark精华问答 | spark的组件构成有哪些?
  2. Linux 操作系统原理 — 日志结构的文件系统与日志文件系统
  3. VMware 虚拟化编程(15) — VMware 虚拟机的恢复方案设计
  4. Linux内核移植之一:内核源码结构与Makefile分析
  5. MinGW 仿 linux 开发环境
  6. onethink后台编辑器 提示:未检测到兼容版本的flash
  7. 我脑中飘来飘去的css魔幻属性
  8. linux服务器的日志管理
  9. Centos Ftp
  10. 【BZOJ】2333: [SCOI2011]棘手的操作