Scope von Variablen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
thomas-hn
User
Beiträge: 1
Registriert: Sonntag 16. September 2018, 15:41

Sonntag 16. September 2018, 16:15

Hallo,

ich habe aktuell folgenden Code in zwei Modulen:

Modul "main":

Code: Alles auswählen

#!/usr/bin/python

import threading
import b

a = 0

def api_a():
    global a
    print("api_a()")
    a = 1

def main():
    global a

    thread_B = b.B_thread()

    print("a = " + str(a)) 
   
    thread_B.start()
    
#    api_a()

    thread_B.join()

    print("a = " + str(a)) 

if __name__ == '__main__':
    main()
Modul "B":

Code: Alles auswählen

#!/usr/bin/python

import threading
import main

class B_thread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        print("Starting " + self.name)
        B_process()
        print("Exiting " + self.name)

def B_process():
    main.api_a()
Wenn ich den Code nun aufrufe erhalte ich die Ausgabe:

Code: Alles auswählen

a = 0
Starting Thread-1
api_a()
Exiting Thread-1
a = 0
Wieso wird "a" nicht auf "1" gesetzt?

Wenn ich stattdessen in Modul "main" die auskommentierte Zeile aktiviere (also: api_a() ), dann wird "a" auf "1" gesetzt. Wieso funktioniert das aber nicht mit dem Aufruf aus dem Thread heraus?
Wieso schreibt die aufgerufene Funktion api_a() nicht die "1" in die Variable?

Auf die Verwendung von Locks für den Variablenzugriff aus dem Thread-Kontext heraus, habe ich in dem Beispiel verzichtet.

Jemand eine Idee?

Vielen Dank,

Thomas
Sirius3
User
Beiträge: 8410
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 17. September 2018, 06:45

Es ist gut, dass dieser Code nicht so funktioniert, wie Du denkst, denn sonst würdest Du ähnlich weiterprogrammieren.

1. Benutze keine globalen Variablen.
2. Benutze keine globalen Variablen zusammen mit Threads
3. Importiere keine Module kreuz und quer.

Ich könnte Dir jetzt im Detail erklären, warum Dein Code nicht funktioniert, aber wenn Du Dich an die drei Regeln hältst, dann bekommst Du auch nicht solch unerwartetes Verhalten.

Um Daten von einem Thread zum Hauptprogramm zurückzubekommen, braucht man Queues. Aus Deinem Beispiel kann ich aber nicht herauslesen, warum Du überhaupt Threads brauchst.

Was willst Du eigentlich erreichen? Wie sieht Dein wirkliches Problem aus?; dann kann man auch helfen, wie man es richtig löst.
Benutzeravatar
__blackjack__
User
Beiträge: 1218
Registriert: Samstag 2. Juni 2018, 10:21

Montag 17. September 2018, 09:15

Um den Punkt 3 von Sirius3 noch mal zu präzisieren: Wenn bei Importen Kreise vorhanden sind, wird's ungemütlich. Wenn sich zwei Module direkt gegenseitig importieren, sind sie auch offensichtlich so eng verbunden, dass sie nicht in zwei verschiedene Module gehören, oder man die Aufteilung anders machen sollte. Meistens ist das ein drittes Modul in das die Sachen kommen die beide Module brauchen.
“Pets are always a great help in times of stress. And in times of starvation too, o'course.” — Terry Pratchett, Small Gods
Antworten