例如,如果一个进程正在生成一个图像,而其他并行进程正在通过get方法访问该图像,我的直觉告诉我在写入图像时访问该图像可能是危险的。
在C ++中,我必须使用互斥锁来确保图像在写入时不被访问,否则我会遇到随机的段错误。但由于python有一些我不完全了解的数据保护机制,我不确定是否需要这样做。
PSEUDO-CODE:
Class Camera(object):
def __init__(self):
self._capture = camera_handler() #camera_handler is a object that loads the driver and lets you control the camera.
self.new_image = None
self._is_to_run = False
def start(self):
self._is_to_run = True
self._thread = thread_object(target=self.run)
self._thread.start()
def run(self):
while(self._is_to_run):
self.new_image = self._capture.update()
cam = Camera()
cam.start()
while True:
image = cam.new_image
result = do_some_process_image(image)
这样安全吗?
答案 0 :(得分:1)
首先,threading
模块使用线程,不不同的进程!
线程和进程之间的关键区别在于前者共享一个地址空间(内存),而后者则没有。
“标准”python实现(CPython)使用全局解释器锁来确保一次只有一个线程可以执行Python字节码。因此,对于可以使用一个字节码指令(如store_fast
)更新的数据,可能不需要互斥锁。当正在修改这样一个变量的线程被中断时,存储已经完成或者没有。
但一般你肯定需要保护数据结构不被多个线程读取和修改。如果一个线程在修改过程中被中断,说一个大字典并且执行被传递给另一个尝试从字典中读取的线程,它可能会发现数据处于不一致的状态。
答案 1 :(得分:1)
Python 不应该在这种情况下发生段错误 - global intepreter lock是你的朋友。然而,即使在你的例子中,相机界面也有可能进入一些不一定表现自己的随机C库。即使这样,它也不会阻止代码中的所有竞争条件,因此您很容易找到不一致的数据。
Python确实有Lock
这是非常低级的,并没有提供太多功能。 Condition
是一种更高级别的类型,更适合实现类似互斥锁的锁定:
# Consume one item
with cv:
while not an_item_is_available():
cv.wait()
get_an_available_item()
# Produce one item
with cv:
make_an_item_available()
cv.notify()
顺便提一下,Python 2中有mutex
,在2.6中已弃用,在Python 3中已删除。
答案 2 :(得分:0)
我认为你要找的是锁对象 - > https://docs.python.org/2/library/threading.html#lock-objects
原语锁是不属于a的同步原语 锁定时的特定线程。在Python中,它目前是最低的 级别同步原语可用,由。直接实现 线程扩展模块。
在你的例子中,我将在像这样的函数中封装对图像的访问
def image_access(self, image_Data = None):
lock = Lock()
lock.acquire()
temp = self.new_image
try:
if image_Data not None:
self.new_image = image_Data
finally:
lock.release()
if image_Data is None:
return temp
有关线程同步的更多信息,请参阅 - > http://effbot.org/zone/thread-synchronization.htm
编辑:
以下是ohter函数的函数
def run(self):
while(self._is_to_run):
self.image_access(self._capture.update())
...
while True:
result = do_some_process_image(cam.image_access())