Seite 1 von 1

Daemon und Thread

Verfasst: Sonntag 23. Januar 2005, 23:47
von flyingfish
Hallo Leute,

ich hab folgendes Problem:

Ich hab einen Daemon, der über eine TCP Socket auf Anfragen wartet.
Bei Anfrage wird eine Seite generiert. Danach kommt eine mehrminütige Berechnung, anschliessend wird wieder eine Seite generiert. Das ganze geschieht in einer While Schleife.

Mein Problem ist nun, dass wenn die Berechnung gerade läuft, logischerweise keine andere Anfrage abgearbeitet werden kann. Ich muss also die Berechnung ausgliedern. Hab es schon mit Thread und Queue versucht, aber irgendwie klappt es nicht. (Der Daemon ist geforked)

Wenn jemand eine Idee :idea: hat, wie das zu lösen ist, wäre ich sehr froh :D

Herzlichen Dank,

flyingfish

Verfasst: Montag 24. Januar 2005, 14:27
von Leonidas
Wenn du ein bischen Code posten könntest, wäre das gar nicht schlecht.

Zum Thema Threads gibt es ein Kapitel im Python Cookbook, das nutze ich recht gerne.

Verfasst: Montag 24. Januar 2005, 14:43
von XT@ngel
Hallo,
ohne Code ist es schwierig zu sagen, wo das Problem liegt.
Aber hier mal ein Beispiel, das keine Probleme mit mehreren Verbindungen hat:

Code: Alles auswählen

Port = 9000
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("",Port))
server.listen(1)

#hauptschleife
while 1:
    Conn,Addr = server.accept()
    if Conn and Addr:
        Client_Data = (Conn,Addr)
        t = thread.start_new_thread(Request_Handler,(Client_Data,))
        print `Addr[0]` + " Connect"

Verfasst: Mittwoch 26. Januar 2005, 19:44
von flyingfish
Hallo, danke fürs erste, aber mein Problem ist eher folgendes:

Ich hab in einem daemon zwei funktionen mit jeweils einer whileschleife
und die sollen nebeneinander laufen, wie mach ich das? threaden ist ja eher schlecht oder, denn ich kann die threads ja nicht beenden...

Code: Alles auswählen

def put_queue():

  while(1):
         ....
       y= received event over socket
       queue.put(y)

def get_queue():

   while(1):
        if not queue.empty():
           x= queue.get()

           verarbeitung....

Verfasst: Mittwoch 26. Januar 2005, 19:58
von Leonidas
flyingfish hat geschrieben:threaden ist ja eher schlecht oder, denn ich kann die threads ja nicht beenden...
Doch, das geht durchaus. Zum beispiel einzelne Funktionen Threads beenden sich, wenn die Funktion sich beendet.

Verfasst: Mittwoch 26. Januar 2005, 21:35
von Gast
Ja, aber wenn ich eine Whileschleife in dem Thread habe...

Verfasst: Mittwoch 26. Januar 2005, 23:42
von Dookie
Hi,

du kannst aber statt while True: dem Thread ein Attribut oder eine globale Variable geben das du abfragst.

Code: Alles auswählen

continue1 = True
continue2 = True

def put_queue():

    while continue1:
        ....
        y= received event over socket
        queue.put(y)

def get_queue():

    while continue2:
        if not queue.empty():
            x= queue.get()

            verarbeitung....

def stop_put_queue():
    global continue1
    continue1 = False

def stop_get_queue():
    global continue2
    continue2 = False
Jetzt kannst du von wo immer auch, mit stop_put_queue den Thread put_queue stoppen und mit stp_get_queue entsprechend get_queue stoppen. Schöner wirds natürlich mit Klassen und darin dann ein Attribut "continue" definieren.


Gruß

Dookie

Verfasst: Mittwoch 26. Januar 2005, 23:43
von XT@ngel
nabend,
Ich hab jetzt mal ein bisschen rumgespielt, und ich hoffe das ich dich richtig verstanden habe....

Das Ergebnis:

Code: Alles auswählen

import threading,  socket

class Queue:
    def __init__(self):
        self.Items = []
        self.Condition = threading.Condition()

    def get(self):
        self.Condition.acquire()
        try:
            if not self.Items:
                self.Condition.wait()
            res = self.Items.pop()
            return res
        finally:
            self.Condition.release()

    def put(self, item):
        self.Condition.acquire()
        try:
            self.Items.append(item)
            self.Condition.notify()
        finally:
            self.Condition.release() 


class tu_was_damit:
    def __init__(self, queue):
        self.queue =  queue

    def run(self):
        while 1:
            Connection = self.queue.get()
            print Connection
            

class Main:
    #Main ist der sender
    def __init__(self, queue):
        self.queue = queue
        Port = 9000
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(("",Port))
        self.server.listen(1)

    def run(self):
        while 1:
            Conn,Addr = self.server.accept()
            if Conn and Addr:
                Client_Data = (Conn,Addr)
                self.queue.put(Client_Data)            
            
     

queue = Queue()
main = Main(queue)
smain = threading.Thread(target=main.run)
tu  = tu_was_damit(queue)
stu = threading.Thread(target=tu.run)
stu.start()
smain.start()
na ja, vielleicht kannst Du damit was anfangen ;)

MfG
andreas

Verfasst: Sonntag 30. Januar 2005, 17:52
von flyingfish
Danke Ihr beiden!
Das hilft mir.

Ich glaube mein Problem ist, dass Python, wenn ich keine Klassen habe, nicht aus dem ersten Thread heraus kann und der weitere Programmablauf dadurch nicht abgerufen wird...

Jedenfall war das so, als ich mit dem kleinen Beispiel mal rum probiert habe. Kann das sein ?

Werde also meinen Daemon mal umschreiben...

Danke nochmal,

flyingfish