2015-01-19 3 views
0

Мне нужно извлечь информацию с помощью tweepy на два шага и обновить глобальную переменную location на первой итерации (проверьте PART1 в моем коде); затем выполните некоторые манипуляции с данными, чтобы вернуть список местоположений (или обновить их), а затем применить вторую часть, где я извлекаю данные из твиттера (PART2).Обновление глобальной varibale между двумя потоками

Вот мой код:

locations=[[-6.38,49.87,1.77,55.81], [-3.38,39.87,1.77,55.81]] 

def Part1(): 
# Doing something here to get locations, then update the location variable 

def Part2(): 
    for l in locations: 
     # then I need to delete the location (l) from the gloabl list 

t1 = Thread(target = Part1) 
t2 = Thread(target = Part2) 

def main(): 
    t1.start() 
    t2.start() 

Это лучший способ сделать это?. Каков рекомендуемый способ сделать location в качестве переменной gloabl и обновить/уничтожить его в обоих потоках.

+0

В Python говорится, что вы никогда не должны изменять список, итерации по нему. Я думаю, если вы повторяете список в одном потоке, а другой поток удаляете элемент, у вас может быть такая же проблема. –

+0

Как насчет того, чтобы не использовать потоки? Просто вызовите Part1(), место обновления, а затем Part2() – BurningKarl

ответ

1

Здесь есть две проблемы: сначала вы должны использовать Queue для locations вместо списка. This question может помочь объяснить, почему очереди должны быть предпочтительными в поточной среде.

Во-вторых, как упоминал Пауло в комментариях, использование конструкции for ... in ... в списке, пока оно изменяется, является плохой идеей. Созданный итератор не будет знать об изменениях в списке, поэтому он может многократно возвращать один и тот же элемент или пропускать элементы в зависимости от того, как вы изменяете список. Поэтому вместо использования итератора над списком мы используем элементы while и pop.

Ваш пример может выглядеть как этот

import threading 
import queue # Queue in python2.x 

def Part1(locations): 
    # Do work to get locations 
    locations.put(location) 

def Part2(locations): 
    # setup API 

    while True: 
     try: 
      # Get a location and do something with it 
      location = locations.get() 
      ... 

     except queue.Empty: 
      # No items in locations, quit 
      break 

def main(): 
    # setup queue and initial values 
    locations = queue.Queue() 
    locations.put([-6.38,49.87,1.77,55.81]) 

    # start the threads 
    t1 = threading.Thread(target=Part1, args=(locations,)) 
    t2 = threading.Thread(target=Part2, args=(locations,)) 
    t1.start() 
    t2.start() 

Обратите внимание, что, как написано, в этом примере предполагается Part1 генерирует места быстрее, чем Part2 потребляет их. Если местоположения когда-либо становятся пустыми, Part2 уйдет, даже если Part1 позже добавит больше объектов. Если это не так, вам придется сменить оператор break на сон и добавить какой-либо способ для Part1, чтобы сигнализировать Part2, что он закончился.

Смежные вопросы