在Python中,我是否需要保护多线程进程之间的数据传输?

时间:2017-02-27 19:40:45

标签: python multithreading

例如,如果一个进程正在生成一个图像,而其他并行进程正在通过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)

这样安全吗?

3 个答案:

答案 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())