Seite 1 von 1

arbeiten mit threads

Verfasst: Sonntag 5. März 2006, 13:10
von madRAM
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

Verfasst: Sonntag 5. März 2006, 13:20
von mitsuhiko
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.

Verfasst: Sonntag 5. März 2006, 13:29
von Hannes-Spz

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

Verfasst: Sonntag 5. März 2006, 13:46
von mitsuhiko
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.

Verfasst: Sonntag 5. März 2006, 13:47
von mitsuhiko
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)

Verfasst: Sonntag 5. März 2006, 14:38
von Joghurt
Das benötigt übrigens Python 2.4

Verfasst: Sonntag 5. März 2006, 15:38
von modelnine
Dürfte ich hier, besonders im Kontext von "Hannes" Antwort, auch noch mal auf:

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

verweisen? ;-)

Re: arbeiten mit threads

Verfasst: Sonntag 5. März 2006, 18:20
von gerold
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
:-)