2016-11-11 1 views
0

Ich habe einen Thread (new_client_thread), der ein Wörterbuch aktualisiert und es ausdrucken. Wenn ich versuche, das Wörterbuch erneut zu drucken, aber vom Hauptthread, wurde das Wörterbuch nicht geändert. Wenn der Thread (new_client_thread) das Wörterbuch erneut ändert, wurden alle Änderungen ebenfalls gespeichert, aber nur innerhalb dieses Threads und nicht im Hauptverzeichnis.Wörterbuch-Update innerhalb der Funktion, aber nicht außerhalb

Das ist mein server.py

from threading import Thread 
from threading import Lock 


def add_client_to_dict(my_id, connect): 
    my_socket_list[int(my_id)] = connect 
    print my_socket_list 


def print_my_socket_list(): 
    print my_socket_list 
    if len(my_socket_list) == 0: 
     print "dictionary is empty" 
     return None 
    for item in my_socket_list: 
     print item 


def connection_failed(connecting): 
    print "deleting" 
    for key in my_socket_list.keys(): 
     if my_socket_list[key] == connecting: 
      my_socket_list.pop(key) 
      print "deleted" 
      connecting.close() 
      break 


def new_clients(): 
    from Class import Socket_control 
    while True: 
     connect = Socket_control.open_socket() 
     thread_listener = Thread(target=Socket_control.recv_msg, args=(connect,)) 
     thread_listener.start() 


def menu(): 
    choice = 1 
    while choice != 0: 
     choice = raw_input("What would you like to do?\n[0] exit.\n[1] print list of computers.") 
     if choice == "1": 
      print_my_socket_list() 
      if len(my_socket_list) == 0: 
       continue 
      computer = raw_input("Choose a computer :") 
      msg = raw_input("Send message: ") 
      my_socket_list[computer].send_message("MSG:" + msg) 


def main(): 

    new_client_thread = Thread(target=new_clients) 
    new_client_thread.start() 
    menu() 

my_socket_list = {} 
my_socket_list["0"] = None 

if __name__ == "__main__": 
    main() 

Diese Steuerung my socket

ist
import socket 
import datetime 
import server 
from mutex import mutex 
def open_socket(): 
    global connect 
    try: 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.bind(("0.0.0.0", 8200)) 
    except socket.error: 
     print "Socket Error" 

    sock.listen(1) 
    connect, addr = sock.accept() 
    return connect 


def recv_msg(connecting): 
    while True: 
     try: 
      data = connecting.recv(1024) 
      if len(data) == 0: 
       server.connection_failed(connect) 
       return None 
      print "recv " + data 
      data = data.decode('utf-8') 
      if data[:4] == "MYID": 
       handle_client_id(data[4:]) 
     except: 
      server.connection_failed(connecting) 
      print "Recv Error" 
      return None 




def handle_client_id(data): 
    my_id = data 
    if my_id == "0": 
     my_id = get_last_number()+1 
     send_message("MYID" + str(my_id)) 
    file_writing_new_client(my_id) 
    server.add_client_to_dict(my_id,connect) 


def send_message(data): 
    try: 
     print "sent " + data 
     connect.send(data) 
    except: 
     print "Sent Error" 
     server.connection_failed(connect) 


def get_last_number(): 
    with open("jennifer_clients_list.txt") as my_file: 
     my_file.seek(0) 
     first_char = my_file.read(1) 
     my_file.seek(0) 
     if not first_char: 
      return 0 
     else: 
      lines = my_file.readlines() 
      print "text: " 
      print lines 
      data = lines[-1].split(" ")[0] 
      return int(data) 
+0

Kann nicht auf lokale Variablen außerhalb zugreifen, müssen 'global' oder' class' für den Zugriff überall verwenden. Aber du verlierst den Synchronismus, wenn die Zugriffsvariable von außen kommt. Das Beste daran, Ergebnisse besser zu speichern als Daten zu speichern! – dsgdfg

Antwort

1

In CPython, sollten Sie keine Schwierigkeiten haben, einen dict in einem Thread zu aktualisieren, und in einem anderen Zugriff (siehe Using a global dictionary with threads in Python).

Die unmittelbare Ursache Ihres Problems ist, dass Sie versuchen, das Wörterbuch mit dem falschen Schlüssel zu referenzieren. Wenn Sie die ID im Wörterbuch speichern, konvertieren Sie sie zunächst in eine int, aber wenn Sie über den Hauptthread darauf zugreifen, verwenden Sie den vom Benutzer bereitgestellten Eingang str; d.h. int('88') ist nicht derselbe Schlüssel wie '88'.

Wenn Sie die Zeile ändern:

my_socket_list[computer].send_message("MSG:" + msg) 

zu:

my_socket_list[int(computer)].send_message("MSG:" + msg) 

Sie werden zum nächsten Fehler Fortschritt (das ist, dass das socket Objekt nicht über eine send_message Methode, aber wenn Sie ändern das zu .send, es wird funktionieren).

Um zum ursprünglichen Thema zurückzukehren, ist es in der Regel eine schlechte Idee, den Code auf ein Implementierungsdetail wie CPython's Global Interpreter Lock zu verlassen, also würde ich vorschlagen, den Zugriff auf Ihr Wörterbuch mit Lock zu synchronisieren.

Verwandte Themen