Daemon und Thread

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
flyingfish
User
Beiträge: 33
Registriert: Sonntag 23. Januar 2005, 23:36

Sonntag 23. Januar 2005, 23:47

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
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 24. Januar 2005, 14:27

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
XT@ngel
User
Beiträge: 256
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

Montag 24. Januar 2005, 14:43

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"
flyingfish
User
Beiträge: 33
Registriert: Sonntag 23. Januar 2005, 23:36

Mittwoch 26. Januar 2005, 19:44

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....
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 26. Januar 2005, 19:58

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Gast

Mittwoch 26. Januar 2005, 21:35

Ja, aber wenn ich eine Whileschleife in dem Thread habe...
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 26. Januar 2005, 23:42

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
[code]#!/usr/bin/env python
import this[/code]
XT@ngel
User
Beiträge: 256
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

Mittwoch 26. Januar 2005, 23:43

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
flyingfish
User
Beiträge: 33
Registriert: Sonntag 23. Januar 2005, 23:36

Sonntag 30. Januar 2005, 17:52

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
Antworten