Kończenie wątków w python

0

Dzień dobry.
Mam następujący problem:
uruchamiam wątek główny, który uruchamia z kolei 5 innych wątków, i po określonym czasie, wątek główny powinien zamknąć tamtych pięć. Te wątki coś tam sobie robią w pętli while i nie potrafię zmienić wartości tego warunku gdy już czas upłynie.
Jak to zrobić?

0
......
def filozof(liczba):
    print("Filozof nr %s" % str(liczba+1))
    osoba = Filozof()
    osoba.paleczki = stol.sztucce[liczba]
    print(osoba.paleczki)
    while stol.status:
            osoba.mysl()
            osoba.jedz()
    print('Filozof nr %s jadl %s razy' % (liczba, osoba.licznik))
......
print('funkcja glowna')
stol = Stol()
stol.start()

for i in range(5):
    stol.zapros(i)
for osoba in stol.filozofowie:
    osoba.join()        

Myślę, że tutaj gdzieś będzie problem. Kompiluje się, działa i tylko nie chce przestać - a powinien, po określonym czasie.
A, ha - klasa Stół jest deklarowana jako wątek(class Stol(threading.Thread):) - może to jest nie potrzebne..

0
import threading
import random
import time
import datetime
import sys

class Stol(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.czas = 20
        self.status = True
        self.pierwsza = True
        self.druga = True
        self.trzecia = True
        self.czwarta = True
        self.piata = True
        self.paleczki = [self.pierwsza, self.druga, self.trzecia, self.czwarta, self.piata]
        self.filozofowie = []
        self.sztucce = [[0,1],[1,2],[2,3],[3,4],[4,0]]
    def odswiez(self):
        self.pierwsza = self.paleczki[0]
        self.druga = self.paleczki[1]
        self.trzecia = self.paleczki[2]
        self.czwarta = self.paleczki[3]
        self.piata = self.paleczki[4]
        self.paleczki = [self.pierwsza, self.druga, self.trzecia, self.czwarta, self.piata]

    def polozPaleczke(self,paleczka):
        if self.paleczki[paleczka] == False:
            self.paleczki[paleczka] = True
            print("Kladę pałeczkę nr %s" % str(paleczka+1))
            self.odswiez()
        else:
            print("Tam już jest pałeczka")
            self.odswiez()

    def wezPaleczke(self, paleczka):
        if self.paleczki[paleczka] == False:
            print("BRAK PALECZKI nr %s" % paleczka)
            print(self.paleczki)
            self.odswiez()
            print(self.paleczki)
        else:
            print("biorę pałeczkę nr %s" % paleczka)
            self.paleczki[paleczka] = False
            self.odswiez()


    def zapros(self, ktory):
        print('Zapraszam filozofa')
        osoba = threading.Thread(target=filozof, args=(ktory,))
        print('przyszedl filozof..- ten %s' % str(ktory+1))
        osoba.start()
        #osoba.join()
        self.filozofowie.append(osoba)

    def zakoncz(self):
        self.status = False

class Filozof(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.glod = False
        self.paleczki = []
        self.prawa = False
        self.lewa = False
        self.licznik = 0

    def odswiez(self):
        self.lewa = stol.paleczki[self.paleczki[0]]
        self.prawa = stol.paleczki[self.paleczki[1]]

    def mysl(self):
        czas = random.randint(0,3)
        print("myślę przez %s sekundy...zZzz..." % czas )
        time.sleep(czas)
        print("..zgłodniałem.")
        self.glod = True
    def wezPaleczke(self,paleczka):
        if stol.paleczki[(paleczka)] == True:
            stol.wezPaleczke(paleczka)
        else:
            print('zaczekam')

    def odloz(self):

        print('paleczka lewa = %s' % self.lewa)
        print('paleczka prawa = %s' % self.prawa)
        print(self.paleczki)
        print('odkladam paleczki')
        stol.paleczki[self.paleczki[0]] = True
        self.lewa = False
        stol.paleczki[self.paleczki[1]] = True
        self.prawa = False

    def jedz(self):
        czas = random.randint(0,3)
        print('paleczka lewa = %s' % self.lewa)
        print('paleczka prawa = %s' % self.prawa)
        print('Bede jadł')
        print(stol.paleczki)
        if self.glod == False:
            print("nie chcę jeść!!")
        else:
            print('paleczki %s' % self.paleczki)
            if self.lewa == True:
                self.wezPaleczke(self.paleczki[1])
                self.prawa = True
            else:
                print('brak leej paleczki')
                if stol.paleczki[(self.paleczki[0])] == True:
                    self.wezPaleczke((self.paleczki[0]))
                    self.lewa = True
                    if stol.paleczki[self.paleczki[1]] == True:
                        self.wezPaleczke(self.paleczki[1])
                        self.prawa = True
                    else:
                        print('zaczekam')
                else:
                    print('zaczekam')
        if  ((self.lewa == True) and (self.prawa == True)):
            print('teraz moge zjesc..')
            time.sleep(czas)
            self.glod = False
            self.odloz()
            self.licznik = self.licznik + 1
        print('paleczka lewa = %s' % self.lewa)
        print('paleczka prawa = %s' % self.prawa)

def filozof(liczba):
    print("Filozof nr %s" % str(liczba+1))
    osoba = Filozof()
    osoba.paleczki = stol.sztucce[liczba]
    print(osoba.paleczki)
    while stol.status:
        if stol.status == False:
            break
        else:
            osoba.mysl()
            osoba.jedz()

    print('Filozof nr %s jadl %s razy' % (liczba, osoba.licznik))

def procesStol():
    start = time.time()
    print("Zaczynam watek glowny")
    #stol.czas = input('Ile czasu dasz filozofom?')

    for i in range(5):
        stol.zapros(i)
    if time.time() - start > stol.czas:
        stol.status = False

    print('czas trwania %s' % (time.time() - start))
    print('wynoszę stół.')


print('funkcja glowna')
stol = Stol()
stol.start()

for i in range(5):
    stol.zapros(i)
for osoba in stol.filozofowie:
    osoba.join()

0
JakubD napisał(a):
class Stol(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.czas = 20
        self.status = True
        self.pierwsza = True
        self.druga = True
        self.trzecia = True
        self.czwarta = True
        self.piata = True
        self.paleczki = [self.pierwsza, self.druga, self.trzecia, self.czwarta, self.piata]
        self.filozofowie = []
        self.sztucce = [[0,1],[1,2],[2,3],[3,4],[4,0]]
    def odswiez(self):
        self.pierwsza = self.paleczki[0]
        self.druga = self.paleczki[1]
        self.trzecia = self.paleczki[2]
        self.czwarta = self.paleczki[3]
        self.piata = self.paleczki[4]
        self.paleczki = [self.pierwsza, self.druga, self.trzecia, self.czwarta, self.piata]

Czy w przypadku problemu 40 filozofów stworzyłbyś 40 property w stylu self.trzydziestaCzwarta i nimi żonglował? :P To już jest potencjalne źródło problemu, masz milion różnych miejsc (listy, property, listy list) które przechowują stan czegoś co logicznie powinno być jedną i tą samą pałeczką. To się prosi o problemy.

    def polozPaleczke(self,paleczka):
        if self.paleczki[paleczka] == False:
            self.paleczki[paleczka] = True
            print("Kladę pałeczkę nr %s" % str(paleczka+1))
            self.odswiez()
        else:
            print("Tam już jest pałeczka")
            self.odswiez()

Czyli pałeczki mogą się cudownie rozmnażać? Problem 5 filozofów chyba nie polegał na cudownym rozmnożeniu :]

   def odswiez(self):
       self.lewa = stol.paleczki[self.paleczki[0]]
       self.prawa = stol.paleczki[self.paleczki[1]]

Czyli każdy filozof bierze pierwszą i drugą pałeczkę niezależnie od tego, którym jest filozofem? To tak nie działa

    def wezPaleczke(self,paleczka):
        if stol.paleczki[(paleczka)] == True:
            stol.wezPaleczke(paleczka)
        else:
            print('zaczekam')

Tak właściwie, to cały proces brania pałeczek powinien się odbywać w sekcji krytycznej, a z tego co widzę tak nie jest - w momencie, gdy filozof decyduje, czy zabrać pałeczkę i ją faktycznie bierze, jej stan może się zmienić.

    def jedz(self):
        czas = random.randint(0,3)
        print('paleczka lewa = %s' % self.lewa)
        print('paleczka prawa = %s' % self.prawa)
        print('Bede jadł')
        print(stol.paleczki)
        if self.glod == False:
            print("nie chcę jeść!!")

Ten if chyba nie jest do końca potrzebny? Skoro filozof postanawia jeść to znaczy że jest głodny.

        else:
            print('paleczki %s' % self.paleczki)
            if self.lewa == True:
                self.wezPaleczke(self.paleczki[1])
                self.prawa = True
            else:
                print('brak leej paleczki')
                if stol.paleczki[(self.paleczki[0])] == True:
                    self.wezPaleczke((self.paleczki[0]))
                    self.lewa = True
                    if stol.paleczki[self.paleczki[1]] == True:
                        self.wezPaleczke(self.paleczki[1])
                        self.prawa = True
                    else:
                        print('zaczekam')
                else:
                    print('zaczekam')
        if  ((self.lewa == True) and (self.prawa == True)):
            print('teraz moge zjesc..')
            time.sleep(czas)
            self.glod = False
            self.odloz()
            self.licznik = self.licznik + 1
        print('paleczka lewa = %s' % self.lewa)
        print('paleczka prawa = %s' % self.prawa)

Sprawdzasz stan pałeczek w co najmniej 3 różnych miejscach, bez sekcji krytycznej i generalnie odnoszę wrażenie, że dość chaotycznie. Odnoszę wrażenie, że w pierwszej kolejności powinieneś uporządkować zarządzanie ich stanem tzn. wydzielić to do jednego miejsca, opakować w sekcję krytyczną i tak dalej.

def filozof(liczba):
    print("Filozof nr %s" % str(liczba+1))
    osoba = Filozof()
    osoba.paleczki = stol.sztucce[liczba]

Trochę się idzie pogubić w Twoim kodzie. Przede wszystkim, dlaczego tworzysz obiekt Filozof po czym go inicjalizujesz w jakiejś zewnętrznej funkcji/metodzie, zamiast w jego metodzie _init_()? No i zrobiłbym porządek z nazewnictwem, bo w tych sztućcach i pałeczkach się idzie pogubić.

0

Czy w przypadku problemu 40 filozofów stworzyłbyś 40 property w stylu self.trzydziestaCzwarta i nimi żonglował?

  • Raczej nie.

Czyli każdy filozof bierze pierwszą i drugą pałeczkę niezależnie od tego, którym jest filozofem? To tak nie działa

  • Nie. Po utworzenia obiektu klasy Filozof, przypisuję mu które pałeczki ze stołu będzie miał do dyspozycji, po czym wewnątrz obiektu przypisuję do prawej i lewej ręki.

Tak właściwie, to cały proces brania pałeczek powinien się odbywać w sekcji krytycznej, a z tego co widzę tak nie jest - w momencie, gdy filozof decyduje, czy zabrać pałeczkę i ją faktycznie bierze, jej stan może się zmienić.

  • Według mnie tak się dzieje gdyż metoda weźPaleczkę u filozofa, wywołuje tylko właściwą metodę w obiekcie stół, i tam zmienia stan stosownych pałeczek.

Z tego co wypluwa na ekran wygląda jakby dobrze działało, tylko zatrzymać go nie potrafię.

Wielkie dzięki za analizę kodu:)
Wiem że jest chaotyczny..

0

...
Filozof nr 4 jadl 4 razy
myślę przez 1 sekundy...zZzz...
..zgłodniałem.
paleczka lewa = True
paleczka prawa = False
Bede jadł
[True, True, True, False, False]
paleczki [1, 2]
biorę pałeczkę nr 2
teraz moge zjesc..
..zgłodniałem.
paleczka lewa = False
paleczka prawa = False
Bede jadł
[True, True, False, False, False]
paleczki [2, 3]
brak leej paleczki
zaczekam
paleczka lewa = False
paleczka prawa = False
Filozof nr 2 jadl 3 razy
myślę przez 2 sekundy...zZzz...
..zgłodniałem.
paleczka lewa = False
paleczka prawa = False
Bede jadł
[True, True, False, False, False]
paleczki [4, 0]
brak leej paleczki
zaczekam
paleczka lewa = False
paleczka prawa = False
Filozof nr 4 jadl 4 razy
myślę przez 1 sekundy...zZzz...
paleczka lewa = True
paleczka prawa = True
...

0

Działa:), trzeba było wpisać cyferkę w osoba.join("tutaj")

1 użytkowników online, w tym zalogowanych: 0, gości: 1