Скрипт на Python с многопоточностью, показывающий неправильную последовательность из последовательности переданного списка

#python #multithreading #queue #python-multithreading #fifo

Вопрос:

Я использую метод fetch_parallel для загрузки файлов fits и хочу, чтобы они были в последовательности, чтобы я мог отображать их с помощью matplotlib, но каждый раз, когда я запускаю сценарий, существует отдельная последовательность возвращаемых объектов, что означает, если я передам

 urls=['foo1','foo2','foo3']

# the return sequence should be:
return_objects = ['obj1','obj2','obj3']

# but i am getting random sequence like:
return_objects = ['obj3','obj1','obj2']
 
  1. Это из-за раннего присоединения потока, а последнее из-за прогресса загрузки?
  2. Как мне вернуться в той же последовательности, что и при передаче?
 def fetch_parallel(urls):
  result = queue.Queue()
  threads = [threading.Thread(target=read_url, args = (url,result)) for url in urls]
  for t in threads:
      t.start()
  for t in threads:
      t.join()
  return result
 

обновление : метод read_url

 
def read_url(url, queue):
  data = urllib.request.urlopen(url, timeout=300)
  fget = fts.getdata(data, header=True)
  print('Fetched %s from %s' % (len(fget), url))

  queue.put(fget)
 

Комментарии:

1. что такое функция read_url? медленный веб-сайт может вызвать вашу проблему, но вы можете решить ее, используя переменную (номер индекса) в списке URL-адресов

2. добавлен метод read_url в качестве обновленного текста. извините, я все еще учусь, как мне использовать индекс между и start() и join() ?

3. Проверьте ответ, не проверял, но это идея, некоторые изменения для python3 (xrange -> диапазон)

Ответ №1:

Попробуйте эти изменения, результат должен быть «общим» списком и записывать результат в том же порядке, что и URL в URL-адресах

 result = list(xrange(len(urls)))
threads = [threading.Thread(target=read_url, args = (urls[i_url], i_url, result)) for i_url in xrange(len(urls))]


def read_url(url, i_url, queue):
    ...

    #queue.put(fget)
    queue[i_url] = fget