1

我很困惑为什么在线程中调用的函数总是返回相同的值。我已经确认每次调用的参数都不同。如果我在获取锁后调用该函数,则该函数返回正确的值。这显然违背了使用线程的目的,因为这个函数只是按顺序调用,一个线程接一个。这就是我所拥有的。该函数称为“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 模块来复制函数,包括深拷贝和浅拷贝并调用函数 copy,但这些都不起作用。

4

0 回答 0