bringen mir threads was ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

ich bin für eine web applikation zu python gewechelt, weil in php keine threads möglich sind.

ich will ca. 20 urls gleichzeitig ansprechen und nach verfügbarkeiten vo produkten fragen (ähnlich preisvergleich seiten, die zig shops absuchen)

jetzt hatte ich mir vorgestellt das mit threads zu machen, lese aber folgendes in der mailing list von python
Because of the GIL, thread pools are not as useful in Python as you
might expect -- they execute one at a time and do not take advantage of
hyper-threading or multiple processors. If that kind of efficiency is
what you are after, then take a look at PyLinda which can coordinate
communication between multiple instances of Python running in separate
threads
was heisst "they execute one at the time" ? das macht ja mal gar keinen sinn dann.

im moment starte ich gleich viele threads wie ich urls habe, nach diesem beispiel von gerold:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import urllib2
import threading
import time


lock = threading.Lock()


def download(url, retvals):
   
    try:
        html = urllib2.urlopen(url).read()
    except urllib2.URLError, exception:
        html = "ERROR: %s" % str(exception)
    lock.acquire()
    retvals.append((url, html))
    lock.release()


def main():
    urls = (
        "http://gerold.bcom.at/",
        "http://halvar.at/",
        "http://lugt.at/",
        "http://microsoft.de/",
        "http://www.python-forum.de/",
        "http://python.org/",
        "http://wallerforum.com/",
        #"http://log-in.fachdid.fu-berlin.de/Archiv/2001/2/Thema/", # braucht zu lange
    )
    retvals = []
    threads = []
    for url in urls:
        threads.append(
            threading.Thread(
                target = download, kwargs = dict(url = url, retvals = retvals)
            )
        )
        threads[-1].start()
        time.sleep(0.2)
   
    # Warten bis alle fertig sind
    for thread in threads:
        thread.join()
       
    for url, html in retvals:
        print url
        if html.startswith("ERROR"):
            print "Achtung Fehler!"
        print html[:100]
        print


if __name__ == "__main__":
    main()
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Keine direkte Antwort auf deine Frage, aber ich verweise mal auf etwas, was ich auch schonmal in einem anderen Thread gesagt habe:
Rebecca hat geschrieben:Multithreading und Multiprocessing ist sinnvoll fuer CPU-lastige nebenlaeufige Programme, fuer IO-lastige Programme aber eventuell nicht optimal. Es gibt noch eine andere Moeglichkeit! Ich zitiere mal die Doku vom asyncore-Modul:
There are only two ways to have a program on a single processor do ``more than one thing at a time.'' Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without actually using multiple threads. It's really only practical if your program is largely I/O bound. If your program is processor bound, then pre-emptive scheduled threads are probably what you really need. Network servers are rarely processor bound, however.

If your operating system supports the select() system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking place in the ``background.'' Although this strategy can seem strange and complex, especially at first, it is in many ways easier to understand and control than multi-threaded programming. The asyncore module solves many of the difficult problems for you, making the task of building sophisticated high-performance network servers and clients a snap. For ``conversational'' applications and protocols the companion asynchat module is invaluable.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

debian75 hat geschrieben:im moment starte ich gleich viele threads wie ich urls habe
Hallo debian75!

Starte zum Testen einmal die einzelnen HTTP-Anfragen hintereinander und einmal in Threads. Was ist schneller?

Wie ich GIL verstanden habe, kümmert es sich darum, dass sich einzelne Python-Befehle nicht in die Quere kommen können. Ein Befehl wie ``x = 1`` sperrt die Ausführung aller anderen Befehle so lange, bis ``x = 1`` durchgeführt wurde. So kann nicht gleichzeitig ein anderer Thread der Variable x einen anderen Wert zuweisen. Das gilt für einzelne Python-Befehle und nicht für ganze, in Python geschriebene, Funktionen. Diese bestehen ja aus einzelnen Befehlen. Nur die einzelnen Befehle und nicht ganze Funktionen werden geblockt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Das GIL darf man nicht überbewerten :-) Ja, du kannst mit Python Threads nicht zwei Prozessorkerne ausnützen, aber das brauchst du auch für dein einfaches Beispiel nicht.

Aber Threads sind insgesamt eine problematische Sache, nicht nur in Python. Man muss immer für jede Aufgabe das richtige Werkzeug nehmen. Und in Python hast du da genug. Threads mit einem Interpreterlock, Grüne Threads (greenlets), und dann kannst du noch forken. Und Parallel Python macht das auch sehr einfach :-)
TUFKAB – the user formerly known as blackbird
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

hab da was interessantes gefunden:

http://www.pyzine.com/Issue001/Section_ ... reter.html
In Example #3, we're using the urllib module, which uses blocking sockets under the covers to make HTTP connections. The socket module releases the GIL, so both threads in example 3b can run simultaneously. Therefore, the single-threaded version (3a) is going to run slower in this case.
so wie das ausschaut gibts bei urlopen keinen GIL ? das macht dan threads wieder sinnnvoll für mich. ok, ich kann das zeug nicht gleichzeitig parsen aber immerhin kann ich die daten gleichzeitig holen.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

da fällt mir gleich noch eine frage ein. wenn urlopen den GIL killt, dann kann ich die html seiten für alles 20 urls gleichzeitig laden.

im moment parse ich die daten auch jeweils im gleichen thread. das heisst aber, dass der thread eben doch blockiert, weil parsen eben wieder GIL anfällig ist.

theoretisch müsste es besser sein, die html daten aus urlopen einfach in ne variable zu schreiben und sonst nichts weiter zu machen im thread.

am schluss, wenn alle threads fertig sind einfach diese eine grosse variable parsen...

sollte doch schneller sein oder ?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

`urlopen` killt da nicht den GIL (wie bist du auf die Formulierung gekommen), sondern es benutzt das `sockets`-Modul, welches in C geschrieben ist. Der GIL betrifft nur Python-Module, keine C-Module.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@debian75: Auch die Verarbeitung solltest Du in den Threads erledigen. Es können zwar nicht zwei Verarbeitungen wirklich gleichzeitig laufen, aber es kann durchaus etwas verarbeitet werden, solange ein anderer Thread im `socket`-Code steckt. Das Herunterladen wird ja nicht bei allen URLs gleich schnell laufen.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

Leonidas hat geschrieben:`urlopen` killt da nicht den GIL (wie bist du auf die Formulierung gekommen), sondern es benutzt das `sockets`-Modul, welches in C geschrieben ist. Der GIL betrifft nur Python-Module, keine C-Module.
du musst dir den GIL als "endboss" in nem game vorstellen, der zwischen dir und dem ultimativen "epic" item steht....und das liebe C killt den sack.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das "liebe C" killt den GIL nicht, das "liebe C" (und genauer der in C geschriebene Interpreter) aktiviert ihn und deaktiviert ihn ja selbst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Der "spawnt" danach aber $GOTT sei Dank wieder. Ohne den gäb's nämlich ganz schönes Chaos.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

BlackJack hat geschrieben:Der "spawnt" danach aber $GOTT sei Dank wieder. Ohne den gäb's nämlich ganz schönes Chaos.
sie spawnen immer wieder :) ^^
Antworten