我有一个更新字典并打印它的线程(new_client_thread)。 当我尝试再次从主线程打印字典时,字典没有更改。当线程(new_client_thread)再次更改字典时,所有更改也被保存,但只保存在此线程内,而不是在主线内。
这是我的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()
这是我的套接字控件
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 :(得分:1)
在CPython中,你应该在一个线程中更新dict并在另一个线程中访问它时没有问题(参见Using a global dictionary with threads in Python)。
问题的直接原因是您尝试使用错误的密钥引用字典。当您将ID存储在字典中时,您首先将其转换为int
,但是当您从主线程访问它时,您正在使用用户提供的str
输入;即int('88')
不与'88'
相同的密钥。
如果您更改了该行:
my_socket_list[computer].send_message("MSG:" + msg)
为:
my_socket_list[int(computer)].send_message("MSG:" + msg)
您将进入下一个错误(即socket
对象没有send_message
方法,但如果您将其更改为.send
,则会有效。
要回到最初的主题,将代码依赖于CPython的全局解释器锁等实现细节通常是个坏主意,因此我建议使用Lock
同步对字典的访问。