одновременное выполнение нескольких потоков в python – возможно ли это?

Я пишу маленький искатель, который должен получать URL несколько раз, я хочу, чтобы все потоки запускались одновременно (одновременно).

Я написал небольшой фрагмент кода, который должен это сделать.

import thread from urllib2 import Request, urlopen, URLError, HTTPError def getPAGE(FetchAddress): attempts = 0 while attempts < 2: req = Request(FetchAddress, None) try: response = urlopen(req, timeout = 8) #fetching the url print "fetched url %s" % FetchAddress except HTTPError, e: print 'The server didn\'t do the request.' print 'Error code: ', str(e.code) + " address: " + FetchAddress time.sleep(4) attempts += 1 except URLError, e: print 'Failed to reach the server.' print 'Reason: ', str(e.reason) + " address: " + FetchAddress time.sleep(4) attempts += 1 except Exception, e: print 'Something bad happened in gatPAGE.' print 'Reason: ', str(e.reason) + " address: " + FetchAddress time.sleep(4) attempts += 1 else: try: return response.read() except: "there was an error with response.read()" return None return None url = ("http://www.domain.com",) for i in range(1,50): thread.start_new_thread(getPAGE, url) 

из журналов apache не кажется, что потоки выполняются одновременно, есть небольшой промежуток между запросами, он почти не обнаруживается, но я вижу, что потоки не очень параллельны.

Я читал о GIL, есть ли способ обойти его без вызова кода C \ C ++? Я не могу понять, как возможна резьба с GIL? python в основном интерпретирует следующий поток, как только он заканчивается предыдущим?

Благодарю.

5 Solutions collect form web for “одновременное выполнение нескольких потоков в python – возможно ли это?”

Как вы заметили, GIL часто препятствует параллельной работе потоков Python.

Однако это не всегда так. Одним из исключений является код, связанный с I / O. Когда поток ожидает завершения ввода-вывода, он, как правило, выпустил GIL перед входом в ожидание. Это означает, что другие потоки могут добиться прогресса в то же время.

В общем, однако, multiprocessing – это более безопасная ставка, когда требуется истинный параллелизм.

Я читал о GIL, есть ли способ обойти его без вызова кода C \ C ++?

На самом деле, нет. Функции, вызываемые ctypes, будут освобождать GIL для продолжительности этих вызовов. Функции, которые выполняют блокировку ввода-вывода, также освободят его. Существуют и другие подобные ситуации, но они всегда включают код вне основного цикла интерпретатора Python. Вы не можете отпустить GIL в свой код Python.

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

 #!/usr/bin/env python import threading import datetime import urllib2 allgo = threading.Condition() class ThreadClass(threading.Thread): def run(self): allgo.acquire() allgo.wait() allgo.release() print "%s at %s\n" % (self.getName(), datetime.datetime.now()) url = urllib2.urlopen("http://www.ibm.com") for i in range(50): t = ThreadClass() t.start() allgo.acquire() allgo.notify_all() allgo.release() 

Это приблизит вас к тому, чтобы все извлечения произошли в одно и то же время, НО :

  • Сетевые пакеты, выходящие из вашего компьютера, будут проходить по проводке Ethernet последовательно, а не одновременно,
  • Даже если у вас на вашем компьютере имеется 16+ ядер, некоторые маршрутизаторы, мосты, модем или другое оборудование между вашей машиной и веб-хостом, вероятно, будут иметь меньше ядер и могут сериализовать ваши запросы,
  • Веб-сервер, из которого вы извлекаете материал, будет использовать вызов accept() для ответа на ваш запрос. Для правильного поведения, которое реализовано с использованием глобальной блокировки сервера, чтобы гарантировать, что только один серверный процесс / поток отвечает на ваш запрос. Даже если некоторые из ваших запросов поступают на сервер одновременно , это приведет к некоторой сериализации.

Вероятнее всего, ваши запросы будут перекрываться в большей степени (т.е. другие, начиная с некоторого завершения), но вы никогда не получите все ваши запросы для запуска одновременно на сервере.

Вы также можете посмотреть на такие вещи, как будущее pypy, где у нас будет программная переходная память (таким образом, с GIL). Это всего лишь исследование и интеллектуальное издевательство в данный момент, но оно может перерасти в нечто большое.

Если вы запустите свой код с Jython или IronPython (и, возможно, PyPy в будущем), он будет работать параллельно

  • Действительно ли Python GIL на переводчика?
  • Зеленые нити и поток в python
  • Как избежать предупреждения gcc в расширении Python C при использовании Py_BEGIN_ALLOW_THREADS
  • Что такое глобальный шлюз интерпретатора (GIL)?
  • Многопроцессорность бесполезна с urllib2?
  • Проблема с GIL в глобальном интерпретаторе python
  • Python требует GIL. Но Jython & IronPython этого не делают. Зачем?
  • Обходной путь Python Global Interpreter Lock (GIL) для многоядерных систем с использованием набора задач в Linux?
  • Python - лучший язык программирования в мире.