einfacher SMTP-Server

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 30. November 2007, 19:35

Hallo droptix!

Code: Alles auswählen

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

import signal
import time


class Signals(object):
    canceled = False
    reload_it = False
signals = Signals()


def signal_handler(signum, frame):
    print 'Signal handler called with signal', signum
    if signum == signal.SIGTERM:
        signals.canceled = True
    elif signum == signal.SIGHUP:
        signals.reload_it = True


def main():
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGHUP, signal_handler)
    
    while True:
        if signals.canceled:
            print "Canceled"
            break
        if signals.reload_it:
            signals.reload_it = False
            print "Reloaded"
            continue
        time.sleep(1)
        print "."


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 30. November 2007, 19:43

Also a) war wirklich nicht so schwer.

Code: Alles auswählen

import signal, time

class Listener(object):
    def complain(self, signum, frame):
        self.loop = False
    
    def run(self):
        signal.signal(signal.SIGHUP, self.complain)
        runs = 0
        while True:
            runs += 1
            print "Starting run %d" % runs
            self.loop = True
            while self.loop:
                time.sleep(1)
        
            
Listener().run()
Den Handler zu SIGTERM habe ich mir gespart, da das Programm beendet wird, auch wenn man nicht darauf reagiert. Wenn man vor dem Beenden Code ausführen will, würde ich eher auf `atexit` zurückgreifen.

b) habe ich mir gespart, stattdessen kill -s HUP `pidof python` verwendet.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Samstag 1. Dezember 2007, 12:41

Hallo, Gerold!
In Deinem Beispiel leuchtet mir die Objektorientierung nicht ein. Wenn man eine Klasse Signals schafft, sollte man dann nicht signal_handler als Methode dieser Klasse konstruieren anstatt als globale Funktion? Wenn man aber doch die globale Funktion verwendet, kann man dann nicht auf Signals verzichten und die Klassenattribute als globale Variablen definieren? Man hat ja mit signals sowieso eine globale Variable?
MfG
HWK
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 1. Dezember 2007, 13:29

HWK hat geschrieben:In Deinem Beispiel leuchtet mir die Objektorientierung nicht ein.
Hallo HWK!

Mein Beispiel hat mit OO nichts am Hut. Und globale Variablen? Kenn ich nicht! :twisted:

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Samstag 1. Dezember 2007, 15:12

Zum Glück ist signals keine globale Variable! *duck*
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Samstag 1. Dezember 2007, 15:28

veers hat geschrieben:Zum Glück ist signals keine globale Variable! *duck*
Warum nicht?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 1. Dezember 2007, 16:41

veers hat geschrieben:Zum Glück ist signals keine globale Variable! *duck*
Hallo veers!

Es ist keine Variable die direkt über eine Funktion geändert wird. Geändert werden nur die Attribute *canceled* und *reload_it*. Und ja, ich pfeife auf Singletones. Man kann es ja auch übertreiben. ;-)

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Samstag 1. Dezember 2007, 17:04

Hallo, Gerold!
Ich will hier ja keine Grundsatzdiskussion beginnen und schon gar nicht Dein Beispiel-Script angreifen. Aber rein "informativ" für einen "Nicht-Informatiker" wie mich:
1. Ich dachte, Klassen dienen dazu, Methoden und Attribute zu kapseln. Warum dann signal_handler als Funktion? Oder ist es üblich, Python-Klassen wie C-Structs allein zur Speicherung von Daten zu verwenden?
2. signals ist ja zumindest global, wenn vielleicht auch keine Variable. Ist das denn besser als canceled und reload_it gleich als globale Variablen zu verwenden?
MfG
HWK
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. Dezember 2007, 17:36

HWK hat geschrieben:1. Ich dachte, Klassen dienen dazu, Methoden und Attribute zu kapseln. Warum dann signal_handler als Funktion? Oder ist es üblich, Python-Klassen wie C-Structs allein zur Speicherung von Daten zu verwenden?
Nein, der Handler wäre besser in der Klasse aufgehoben wenn man konsequent OOP durchsetzen will. Siehe beim Beispiel, wo der Handler in der Klasse ist und nur Klassenvariablen modifiziert.
HWK hat geschrieben:2. signals ist ja zumindest global, wenn vielleicht auch keine Variable. Ist das denn besser als canceled und reload_it gleich als globale Variablen zu verwenden?
Nein, globale Variablen sollte man vermeiden. Ich finde die `Signals`-Klasse auch sinnlos, da sie - wie du bereits sagtest - eigentlich ein Struct zu imitieren versucht. Da könnte man auch genauso gut ein Dict verwenden. Oder ein Dict, welches die Keys als Attribute bereit stellt, dann verhält es sich sogar genauso wie die Klasse `Signals` :D

Oder man macht es einfach so wie ich es demonstiere, eine Klasseninstanz die alles lokal regelt und einen eigenen Signal-Handler hat.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Samstag 1. Dezember 2007, 22:38

Danke, Leonidas.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. Dezember 2007, 22:45

Will damit jetzt aber Gerolds Code nicht runtergemacht haben...

Bin jetzt aber eh gestraft, seitdem ich das Layout auf NEO-Layout gesetzt habe dauert jeder Satz eine halbe Ewigkeit. Hoffentlich zahlt sich das aus. :roll:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Sonntag 2. Dezember 2007, 23:28

@Leonidas: Kleiner Bug in deinem Code?
Leonidas hat geschrieben:

Code: Alles auswählen

import signal, time

class Listener(object):
    def complain(self, signum, frame):
        self.loop = False
    
    def run(self):
        signal.signal(signal.SIGHUP, self.complain)
        runs = 0
        while True:
            runs += 1
            print "Starting run %d" % runs
            self.loop = True
            while self.loop:
                time.sleep(1)

Listener().run()
Fehler:
Python hat geschrieben:Traceback (most recent call last):
File "server.py", line 17, in ?
Listener().run()
File "server.py", line 8, in run
signal.signal(signal.SIGHUP, self.complain)
AttributeError: 'module' object has no attribute 'SIGHUP'
Laut help(signal) gibt es folgende Signale:
NSIG = 23
SIGABRT = 22
SIGBREAK = 21
SIGFPE = 8
SIGILL = 4
SIGINT = 2
SIGSEGV = 11
SIGTERM = 15
SIG_DFL = 0
SIG_IGN = 1
Kann mir wer weiter helfen, denn ich finde kein SIGHUP?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 2. Dezember 2007, 23:58

Wenn du ein Modul `signal.py` nennst, ist es schon klar, dass es fehlschlägt. ;) In Gerolds Code ist es ebenso vorhanden und scheint dort zu funktionieren.

Bei mir jedenfalls ging es, ich musste es ja auch erstmal zum laufen bekommen. In Python 2.4 ist es auf jeden Fall definiert, es steht sogar als Beispiel in der Doku:
signal Dokumentation hat geschrieben:All the signal numbers are defined symbolically. For example, the hangup signal is defined as signal.SIGHUP; the variable names are identical to the names used in C programs, as found in <signal.h>.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Montag 3. Dezember 2007, 08:45

droptix hat geschrieben:Kann mir wer weiter helfen, denn ich finde kein SIGHUP?
Hallo droptix!

Nicht jedes Betriebssystem kennt alle Signale. Windows kennt SIGHUP z.B. *nicht*.

Unter Linux hast du diese Signale zur Verfügung (SIG*):

Code: Alles auswählen

In [1]: import signal

In [2]: signal.
signal.NSIG                 signal.SIGPOLL              signal.SIGUSR1              signal.__name__
signal.SIGABRT              signal.SIGPROF              signal.SIGUSR2              signal.__new__
signal.SIGALRM              signal.SIGPWR               signal.SIGVTALRM            signal.__reduce__
signal.SIGBUS               signal.SIGQUIT              signal.SIGWINCH             signal.__reduce_ex__
signal.SIGCHLD              signal.SIGRTMAX             signal.SIGXCPU              signal.__repr__
signal.SIGCLD               signal.SIGRTMIN             signal.SIGXFSZ              signal.__setattr__
signal.SIGCONT              signal.SIGSEGV              signal.SIG_DFL              signal.__str__
signal.SIGFPE               signal.SIGSTOP              signal.SIG_IGN              signal.alarm
signal.SIGHUP               signal.SIGSYS               signal.__class__            signal.default_int_handler
signal.SIGILL               signal.SIGTERM              signal.__delattr__          signal.getsignal
signal.SIGINT               signal.SIGTRAP              signal.__dict__             signal.pause
signal.SIGIO                signal.SIGTSTP              signal.__doc__              signal.signal
signal.SIGIOT               signal.SIGTTIN              signal.__getattribute__
signal.SIGKILL              signal.SIGTTOU              signal.__hash__
signal.SIGPIPE              signal.SIGURG               signal.__init__
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Dienstag 4. Dezember 2007, 08:40

Und da liegt auch der Hund begraben, denn ich hab das unter Windows getestet. Dort spielt das ja auch nur eine Untergeordnete Rolle, da Services/Dienste völlig anders ablaufen.

Und wenn ich schon mal dabei bin: gibt es Scripts, um ein Python-Programm als Dienst zu installieren - wobei das Script selbst entscheidet unter welchem Betriebssystem welche Maßnahmen zu treffen sind? Also unter Unix über init-Script und unter Windows über die pywin32-Extensions?
Antworten