arbeiten mit threads

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
madRAM
User
Beiträge: 14
Registriert: Sonntag 5. März 2006, 11:28
Kontaktdaten:

Sonntag 5. März 2006, 13:10

Hallo zusammen,

ich habe eine Frage, die von alten Hasen wahrscheinlich leicht zu beantworten, mir als Anfänger aber einige Schwierigkeiten bereitet.

Ich möchte in einem Programm mit Threads arbeiten, damit es während das Programm mit dem Benutzer interagiert andere Funktionen - quasie im Hintergrund - weiter arbeiten.

Als Beispiel sei eine Zeitausgabe in einem Menu genommen, oder das Erzeugen eines Images und die Ausgabe eines sich drehenden Kreuzes in curses.

Sowas in der Art. Kann mir jemand ein paar Codebeispiele geben?

Danke,

Chris
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 5. März 2006, 13:20

http://trac.pocoo.org/repos/trunk/pocoo ... orators.py

Das ist ein Teil des pocoo systems. Da gibts einen Dekorator fürs Verschieben einer Funktion in den Hintergrund:

Code: Alles auswählen

from time import sleep

@background
def test():
    sleep(10)
    return "blub"

controller = test()
print controller.running
sleep(4)
print controller.running
sleep(7)
print controller.running
print controller.result
Ich denke der code dort ist leicht verständlich und könnte dir helfen.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
Hannes-Spz
User
Beiträge: 123
Registriert: Sonntag 7. August 2005, 22:42

Sonntag 5. März 2006, 13:29

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\Beere\Desktop\muell.py", line 9, in -toplevel-
    print controller.running
AttributeError: 'str' object has no attribute 'running'
und das "@background" hab ich auch 'rausgestrichen, da sonst
ne fehlermeldung kam...

was also bitteschön meinst du mit dem code-stück'l?

liebe grüße
hannes
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 5. März 2006, 13:46

Hannes-Spz hat geschrieben:und das "@background" hab ich auch 'rausgestrichen, da sonst
ne fehlermeldung kam...
Ich sag da jetzt gar nichts dazu. Man müsste da nämlich vorher den Dekorator aus der GEPOSTETEN url herauskopieren.
was also bitteschön meinst du mit dem code-stück'l?
Ach das hab ich geschrieben, damit ich solche ***** wie dich abfüttere :roll:

Sorry, aber sowas geht mir echt an den Kragen.
TUFKAB – the user formerly known as blackbird
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 5. März 2006, 13:47

Hier bitte der Dekorator extrahiert:

Code: Alles auswählen

import sys
import inspect
import new
import itertools
import threading

class decorator(object):
    """General purpose decorator factory: takes a caller function as
    input and returns a decorator. A caller function is any
    function like this::

        def caller(func, *args, **kw):
            # do something
            return func(*args, **kw)
    """
    def __init__(self, caller):
        self.caller = caller

    def __call__(self, func):
        return self._decorate(func, self.caller)

    def _getinfo(self, func):
        assert inspect.ismethod(func) or inspect.isfunction(func)
        regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
        argnames = list(regargs)
        if varargs:
            argnames.append(varargs)
        if varkwargs:
            argnames.append(varkwargs)
        counter = itertools.count()
        fullsign = inspect.formatargspec(
            regargs, varargs, varkwargs, defaults,
            formatvalue=lambda value: '=defarg[%i]' % counter.next())[1:-1]
        shortsign = inspect.formatargspec(
            regargs, varargs, varkwargs, defaults,
            formatvalue=lambda value: '')[1:-1]
        dic = dict(('arg%s' % n, name) for n, name in enumerate(argnames))
        dic.update(name=func.__name__, argnames=argnames, shortsign=shortsign,
            fullsign = fullsign, defarg = func.func_defaults or ())
        return dic

    def _decorate(self, func, caller):
        """
        Takes a function and a caller and returns the function
        decorated with that caller. The decorated function is obtained
        by evaluating a lambda function with the correct signature.
        """
        infodict = self._getinfo(func)
        if '__call_' in infodict['argnames'] or\
           '__func_' in infodict['argnames']:
            raise NameError, "You cannot use __call_ or __func_ as argument names!"
        execdict = dict(__func_=func, __call_=caller, defarg=func.func_defaults or ())
        if func.__name__ == "<lambda>":
            lambda_src = "lambda %(fullsign)s: __call_(__func_, %(shortsign)s)" \
                        % infodict
            dec_func = eval(lambda_src, execdict)
        else:
            func_src = """def %(name)s(%(fullsign)s):
            return __call_(__func_, %(shortsign)s)""" % infodict
            exec func_src in execdict
            dec_func = execdict[func.__name__]
        dec_func.__doc__ = func.__doc__
        dec_func.__dict__ = func.__dict__
        return dec_func

@decorator
def background(func, *args):
    """
    Run a function in the background.
        Returns a ThreadController object providing a
        running and result property.
    """
    class BackgroundThread(threading.Thread):
        def __init__(self):
            super(BackgroundThread, self).__init__()
            self.running = False
            self.result = None

        def run(self):
            self.running = True
            self.result = func(*args)
            self.running = False

    class ThreadController(object):

        def __init__(self, thread):
            self.thread = thread

        def _get_result(self):
            if self.thread.running:
                raise RuntimeError, 'Thread still running'
            return self.thread.result

        running = property(lambda s: s.thread.running)
        result = property(_get_result)

    t = BackgroundThread()
    t.start()
    return ThreadController(t)
TUFKAB – the user formerly known as blackbird
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Sonntag 5. März 2006, 14:38

Das benötigt übrigens Python 2.4
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Sonntag 5. März 2006, 15:38

Dürfte ich hier, besonders im Kontext von "Hannes" Antwort, auch noch mal auf:

http://www.lugbz.org/documents/smart-questions_de.html

verweisen? ;-)
--- Heiko.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Sonntag 5. März 2006, 18:20

madRAM hat geschrieben:Kann mir jemand ein paar Codebeispiele geben?
Hi Chris!

Hier sind zwei Codebeispiele:
http://www.python-forum.de/viewtopic.php?t=3869

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten