gpt4 book ai didi

python - 如何使用 Python 2.7(可能还有 pyserial)在 Linux 中检查串口是否已经打开(由另一个进程打开)?

转载 作者:IT王子 更新时间:2023-10-29 01:08:42 28 4
gpt4 key购买 nike

我知道还有其他问题与我的问题非常相似,但没有一个能解决我遇到的问题。

我想使用pyserial 来访问串行端口(/dev/tty...),但前提是另一个进程还没有已经打开了。

以下代码片段在我的 Ubuntu 12.04 机器上运行一次时返回四个可用端口。如果我第二次运行它,我希望没有端口可用。遗憾的是,返回了相同的端口列表。看来 pyserial 无法识别另一个进程已经打开了端口。

我希望抛出 SerialException,或者 isOpen() 方法返回 False,但是 pyserial 很乐意打开多个次。

import serial
from serial import tools
from serial.tools import list_ports


def available_ttys():
for tty in serial.tools.list_ports.comports():
try:
port = serial.Serial(port=tty[0])
if port.isOpen():
yield port
except serial.SerialException as ex:
print 'Port {0} is unavailable: {1}'.format(tty, ex)


def main():
ttys = []
for tty in available_ttys():
ttys.append(tty)
print tty

input('waiting ...')


if __name__ == '__main__':
main()

无论我并行运行多少次,这都是输出:

Port ('/dev/ttyS31', 'ttyS31', 'n/a') is unavailable: Could not configure port: (5, 'Input/output error')
...
Port ('/dev/ttyS0', 'ttyS0', 'n/a') is unavailable: Could not configure port: (5, 'Input/output error')
Serial<id=0x7fca9d9f1c90, open=True>(port='/dev/ttyUSB1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
Serial<id=0x7fca9d9f1cd0, open=True>(port='/dev/ttyACM2', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
Serial<id=0x7fca9d9f1e50, open=True>(port='/dev/ttyACM1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
Serial<id=0x7fca9d9f1ed0, open=True>(port='/dev/ttyACM0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
waiting ...

最佳答案

正如@VooDooNOFX 所说,防止其他进程打开同一端口(设备)没有技术限制。但是,在 Linux 上,您可以锁定该文件以防止您的应用程序多次使用同一端口。

import fcntl, serial

s = serial.Serial(0)
fcntl.flock(s.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)

在这种情况下,您的应用程序将尝试在串行端口上获取独占锁 (LOCK_EX)。感谢 LOCK_NB,如果任何其他进程已经锁定串行端口,调用将立即失败 - 通过引发 IOError(或 BlockingIOError 子异常在 Python 3.3 中)。

与其他解决方案相比,这有两个优点:

  1. 您没有引入任何非标准文件,而是使用系统提供的方法,带来更好的互操作性,
  2. 当您的进程退出时,锁会立即释放,因此您不必担心过时的锁。

所以,你的函数看起来像:

def available_ttys():
for tty in serial.tools.list_ports.comports():
try:
port = serial.Serial(port=tty[0])
if port.isOpen():
try:
fcntl.flock(port.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
print 'Port {0} is busy'.format(tty)
else:
yield port
except serial.SerialException as ex:
print 'Port {0} is unavailable: {1}'.format(tty, ex)

关于python - 如何使用 Python 2.7(可能还有 pyserial)在 Linux 中检查串口是否已经打开(由另一个进程打开)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19809867/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com