线程中的Python函数调用始终返回相同的值

时间:2013-10-23 16:57:23

标签: python multithreading

我对为什么在线程中调用的函数总是返回相同的值感到困惑。我已经确认每次调用的参数都不同。如果我在获取锁之后调用该函数,则该函数返回正确的值。这显然违背了使用线程的目的,因为这个函数只是顺序调用,一个接一个的线程。这就是我所拥有的。该函数名为“get_related_properties”,我在代码中记下了它:

class ThreadedGetMultipleRelatedProperties():

    def __init__(self, property_values, **kwargs):
        self.property_values = property_values
        self.kwargs = kwargs
        self.timeout = kwargs.get('timeout', 20)
        self.lock = threading.RLock()

    def get_result_dict(self):
        queue = QueueWithTimeout()
        result_dictionary = {}

        num_threads = len(self.property_values)
        threads = []

        for i in range(num_threads):
            t = GetMultipleRelatedPropertiesThread(queue,
                                                   result_dictionary,
                                                   self.lock)
            t.setDaemon(True)
            try:
                threads.append(t)
                t.start()
            except:
                return {"Error": "Unable to process results at this time." }

        for property_value in self.property_values:
            kwargs_copy = dict.copy(kwargs)
            kwargs_copy['property_value'] = property_value
            queue.put(self.kwargs_copy)

        queue.join_with_timeout(self.timeout)

        # cleanup threads
        for i in range(num_threads):
            queue.put(None)
        for t in threads: t.join()

        return result_dictionary


class GetMultipleRelatedPropertiesThread(threading.Thread):

    def __init__(self, queue, result_dictionary, lock):
        threading.Thread.__init__(self)
        self.queue = queue
        self.result_dictionary = result_dictionary
        self.lock = lock

    def run(self):
        from mixpanel_helpers import get_related_properties
        while True:
            kwargs = self.queue.get()
            if kwargs == None:
                break

            current_property_value = kwargs.get('property_value')
            self.lock.acquire()
            # The function call below always returns the same value if called before acquire
            result = get_related_properties(**kwargs)
            try:
                self.result_dictionary[current_property_value] = result
            finally:
                self.lock.release()

            #signals to queue job is done
            self.queue.task_done()

这是get_related_properties,虽然它会进行其他调用,所以我不确定问题是否存在于此处:

def get_related_properties(property_name,
                           property_value,
                           related_properties,
                           properties={},
                           **kwargs):

    kwargs['exclude_detailed_data'] = True
    properties[property_name] = property_value

    result = get_multiple_mixpanel_results(properties=properties,
                                           filter_on_values=related_properties,
                                           **kwargs)

    result_dictionary = {}
    for related_property in related_properties:
        try:
            # grab the last result here, because it'll more likely have the most up to date properties
            current_result = result[related_property][0]['__results'][0]['label']
        except Exception as e:
            current_result = None

        try:
            related_property = int(related_property)
        except:
            pass

        result_dictionary[related_property] = current_result

    return result_dictionary

另外需要注意的是,我还尝试使用Python的copy module复制函数,包括深层和浅层复制,并调用函数副本,但这些都没有。

0 个答案:

没有答案