weixin_38550240 2024-06-27 11:31 采纳率: 25%
浏览 11
已结题

如何使用python 实现对串口/dev/ttyUSB0进行上锁,使得该串口只能在一个python脚本中使用,其他脚本不能操作这个串口

如何使用python 实现对串口/dev/ttyUSB0进行上锁,使得该串口只能在一个python脚本中使用,其他脚本不能操作这个串口,同时需要实现lock,unlock和checkLock的函数,以下方式为什么无法对/dev/ttyUSB0上锁?

def acquireLock(self):
        """
        @fn acquireLock
        @brief acquire Lock
        @param deviceId (int) : device id
        """
        device = "/dev/ttyUSB0"
        lockfile_fd = open(device, 'w')
        try:
            fcntl.flock(lockfile_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
            print(f"Acquired lock on {device}")
            return lockfile_fd
        except IOError:
            print(f"Failed to acquire lock on {device}")
            return None
    
    def releaseLock(self,
                    lockfile_fd):
        try:
            fcntl.flock(lockfile_fd, fcntl.LOCK_UN)
            print("Released lock")
            return 1
        except IOError:
            print("Failed to release lock", 0x4, 0x2E)
            return -1
        lockfile_fd.close()
        
    def isLocked(self):
        """
        @fn isLocked
        @brief check file lock or not
        @param deviceId (int) : device id
        """
        try:
            lockfile = "/dev/ttyUSB0"
            lockfile_fd = open(lockfile, 'w')
            fcntl.flock(lockfile_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
            fcntl.flock(lockfile_fd, fcntl.LOCK_UN)
            lockfile_fd.close()
            return False #File not locked
        except IOError:
            return True #File locked

  • 写回答

19条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-27 11:31
    关注

    引自免费微信小程序:皆我百晓生

    首先,你提供的代码是基于文件锁的方式来实现对串口的独占访问。这种方法的基本思路是通过在串口对应的文件上添加锁来实现独占访问。然而,这种方法的实际效果取决于操作系统、其他程序和脚本的执行方式等因素。

    对于你的问题,以下是一些分析和建议:

    1. 文件锁机制:在Linux系统中,文件锁确实可以防止其他进程访问文件,但这种方式并不是绝对安全的。有些程序可能会忽略文件锁或使用特殊方式来绕过锁。因此,不能确保你的脚本之外的任何程序都无法访问串口。
    2. 脚本中的代码:你的代码逻辑大体上是正确的,但有一些细节需要注意。例如,在isLocked函数中,你尝试获取锁然后立即释放它来判断文件是否被锁定。这种方法在某些情况下可能会导致死锁,因为如果有其他进程已经获取了锁并且没有释放,你的脚本可能会永远等待获取锁。

    针对上述问题,以下是改进的建议:

    改进的代码

    acquireLock

    • 保持不变。

    releaseLock

    • 删除对lockfile_fd的关闭操作。建议在acquireLock中管理文件的打开和关闭。释放锁后,确保文件描述符被关闭。

    isLocked (修改版本)

    为了避免死锁风险,可以尝试以下方式检测锁:

    • 尝试获取锁但不持有它(使用LOCK_NB非阻塞模式)。
    • 如果获取失败(抛出异常),则判断为已锁定;否则,立即释放锁并返回未锁定状态。

    代码示例:

    def isLocked(self):
        lockfile = "/dev/ttyUSB0"
        try:
            with open(lockfile, 'w') as lockfile_fd:  # 使用with确保文件正确关闭
                fcntl.flock(lockfile_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)  # 尝试获取非阻塞锁
                fcntl.flock(lockfile_fd, fcntl.LOCK_UN)  # 立即释放锁(不持有锁)
            return False  # 文件未锁定
        except IOError:  # 文件被锁定时的IOError异常处理
            return True  # 文件已锁定(或无法获取锁)
    

    注意点:实际使用中可能需要额外的机制来确保脚本间的互斥性。例如,你可以考虑使用操作系统级别的进程间通信机制(如信号量或共享内存)来确保只有一个脚本能够启动和操作串口。但这超出了文件锁的范畴,并可能需要更复杂的实现和调试。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月1日
  • 创建了问题 6月27日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见