Python 如何防止对资源(如USB设备)的并发访问?

Python 如何防止对资源(如USB设备)的并发访问?,python,concurrency,locking,semaphore,superglobals,Python,Concurrency,Locking,Semaphore,Superglobals,我希望能够使用来自多个应用程序的USB设备(例如,我运行一个Flask web应用程序),确保一次只有一个使用它 在我的情况下,我使用继电器打开/关闭门。这扇门大约需要20秒才能打开。在此期间,继电器不应被激活,因为这会把门锁在中间。 提前谢谢 这不完全是对你问题的回答,但可能是关于如何在不使用globals的情况下解决这个问题的另一个想法 你为什么不写一个控制USB设备的小程序呢。此脚本在服务器上运行一次(一个实例),并负责以您需要的方式与设备通信。它还负责并发性 现在,使用此脚本通过管道、套

我希望能够使用来自多个应用程序的USB设备(例如,我运行一个Flask web应用程序),确保一次只有一个使用它

在我的情况下,我使用继电器打开/关闭门。这扇门大约需要20秒才能打开。在此期间,继电器不应被激活,因为这会把门锁在中间。


提前谢谢

这不完全是对你问题的回答,但可能是关于如何在不使用globals的情况下解决这个问题的另一个想法

你为什么不写一个控制USB设备的小程序呢。此脚本在服务器上运行一次(一个实例),并负责以您需要的方式与设备通信。它还负责并发性


现在,使用此脚本通过管道、套接字与web应用程序进行通信,向其发送命令并从中接收结果。

这并不是对您的问题的回答,但可能是关于如何在不使用globals的情况下解决此问题的另一个想法

你为什么不写一个控制USB设备的小程序呢。此脚本在服务器上运行一次(一个实例),并负责以您需要的方式与设备通信。它还负责并发性


现在,使用此脚本通过管道、套接字与web应用程序进行通信,向其发送命令并从中接收结果。

您有许多可能的解决方案

或Python模块提供了一个命名的信号量类。您可以将信号量初始化为1,并让所有web进程在向USB设备发送命令时获取信号量

类似的机制可以通过使用文件锁实现,也可以使用


另一种完全不同的方法是在web服务器进程和USB API之间放置一个新进程。此进程公开了一个API,该API接收来自web服务器工作者的请求,并通过单线程进程将这些请求隐式序列化到USB设备中。

您有许多可能的解决方案

或Python模块提供了一个命名的信号量类。您可以将信号量初始化为1,并让所有web进程在向USB设备发送命令时获取信号量

类似的机制可以通过使用文件锁实现,也可以使用


另一种完全不同的方法是在web服务器进程和USB API之间放置一个新进程。此进程公开一个API,该API接收来自web服务器工作程序的请求,并通过单线程进程隐式地将这些请求序列化到USB设备中。

您可以向配置中添加变量(确保其大写)


您可以将变量添加到配置中(确保其大写)


您是否考虑过使用锁定文件?这将是一个好方法和简单方法,但必须小心使用“安全技巧”,如计时器,以避免由于错误而永久锁定资源。是的,任何文件锁定机制都是如此。您可以在锁文件中写入进程的PID,并在尝试获取锁时检查它是否仍在运行,如有必要,还可以实施额外的超时机制。您是否考虑过使用锁文件?这将很好且简单,但必须小心使用“安全技巧”例如一个计时器,以避免由于错误而永久锁定资源。是的,任何文件锁定机制都是如此。您可以在锁文件中写入进程的PID,并在尝试获取锁时检查它是否仍在运行,如果需要,还可以实现额外的超时机制。我同时运行了该程序的两个实例,它让我获得了这两个实例中的信号量。这正常吗?在这种情况下,posix_ipc或sysv_ipc不能解决我的问题。我很容易就找到了锁。但要注意,在出现错误时不要将其永久锁定(这适用于大多数解决方案)。在创建信号量计数时,您没有将其初始化为1(第三个参数设置为1)。奇怪的是,您的测试可以获取信号量,在我看来,您粘贴的代码没有一个实例应该通过,因为信号量开始锁定。请注意,
aquire
递减计数,
release
递增计数。它们实际上都通过了。我不熟悉信号灯。我假设初始_值为0时,它将开始“锁定”,所有
acquire
s将失败。我应该使用初始值1。这就是你的意思吗?我还尝试了连续两次调用
acquire
(初始值=1),都成功了。有点不对劲,不是吗?我的测试似乎工作正常,我一次只能运行其中一个:我尝试了posix_ipc。我同时运行了该程序的两个实例,它让我获得了这两个实例中的信号量。这正常吗?在这种情况下,posix_ipc或sysv_ipc不能解决我的问题。我很容易就找到了锁。但要注意,在出现错误时不要将其永久锁定(这适用于大多数解决方案)。在创建信号量计数时,您没有将其初始化为1(第三个参数设置为1)。奇怪的是,您的测试可以获取信号量,在我看来,您粘贴的代码没有一个实例应该通过,因为信号量开始锁定。请注意,
aquire
递减计数,
release
递增计数。它们实际上都通过了。我不熟悉信号灯。我假设初始_值为0时,它将开始“锁定”,所有
acquire
s将失败。我应该使用初始值1。这就是你的意思吗?我还尝试了连续两次调用
acquire
(初始值=1),都成功了。所以
app.config['YOUR_GLOBAL'] = 'your global'