为什么我的线程锁在这种情况下失败了?

问题描述 投票:0回答:1

在每个线程中,我想通过函数get_next_page_data以递归方式获取所有数据列表,当我打印出指定数据的长度时,预期的初始参数return_data应该是[]

但输出显示:


0 831
831 387
1218 1000
2218 1000
3218 529
3747 1000
4747 1000
5747 458
6205 1000
7205 1000
8205 616
8821 378
9199 188
9387 1000
10387 957

为什么我的线程锁在这种情况下失败了?


class PullCampaignDataService(object):

    def __init__(self):
        self.account_token_list = self._get_account_access_token()
        self.max_worker = 5
        self.chunk_size = 10
        self.lock = threading.Lock()


    def run(self):
        with ThreadPoolExecutor(max_workers=self.max_worker) as executor:
            executor.map(self._handle_account_campaign, self.account_token_list)


    def _get_account_access_token(self):
        sql = """SELECT xxx WHERE u.status=1 AND d.status<>0"""
        return FbUser.objects.raw(sql)


    def _handle_account_campaign(self,account_token):
        account_id = account_token.account_id
        access_token = account_token.access_token

        try:
           with requests.get(
                        "https://xxxxxxxx&access_token={}" .format(
                            settings.API_VERSION, account_id, access_token))as response:
                try:
                    result_dict = json.loads(response.text)
                    campaign_list = result_dict["data"]
                except KeyError:
                    return
                try:
                    _ = result_dict["paging"]['next']
                    with self.lock:
                        next_campaign_list = self.get_next_page_data(result_dict)
                        campaign_list.extend(next_campaign_list)
                except:
                    pass

        except Exception:
            return

    def get_next_page_data(self, origin_data, return_data=[]):
        try:
            next_page_url = origin_data['paging']['next']
            with requests.get(next_page_url) as response:
                temp_ad_list = json.loads(response.text)["data"]
                print(len(return_data), len(temp_ad_list))
                return_data.extend(temp_ad_list)
                return self.get_next_page_data(json.loads(response.text))
        except KeyError:
            result = return_data
            return_data = []
            return result



PullCampaignDataService().run()

python multithreading
1个回答
0
投票

问题不在于锁 - 它是默认参数。它只被评估一次 - 执行函数定义时。

你所有的线程共享一个实例return_data

查看一个简单的例子:

def append_to_list(el, list_to_append=[]):
    list_to_append.append(el)
    return list_to_append

print(append_to_list(1))
print(append_to_list(2))
© www.soinside.com 2019 - 2024. All rights reserved.