[英]Python global variable is not updating it's value in threads
So, I have a guess-the-number type of game in python and I made a threaded server to accept multiple clients to play at once. 因此,我使用python进行数字猜想的游戏,我制作了一个线程服务器来接受多个客户端同时玩。 A thing I want to do is with every answer (S-smaller, H-higher, W-winner, L-loser) I send from the server to the client, to also send a message telling the client how many clients are currently connected, hence
client_count
. 我想做的就是从服务器发送到客户端的每个答案(S小,H高,W赢,L输),并发送一条消息告诉客户端当前连接了多少个客户端,因此为
client_count
。 The problem is that the first client will always be told that there is 1 client playing, the second one will be told that there are 2 players and so on. 问题在于,第一个客户总是被告知有一个客户在玩,第二个客户将被告知有2个玩家,依此类推。 The global variable
client_count
doesn't seem to update over all the threads. 全局变量
client_count
似乎并未在所有线程上更新。
server.py server.py
__author__ = 'emil'
import socket
import threading
import random
import struct
import time
random.seed()
start = 1
stop = 2 ** 17 - 1
my_num = random.randint(start, stop)
print('Server number: ', my_num)
mylock = threading.Lock()
client_guessed = False
winner_thread = 0
e = threading.Event()
e.clear()
threads = []
client_count = 0
def worker(cs):
global mylock, client_guessed, my_num, winner_thread, client_count, e
my_idcount = client_count
print('client #', client_count, 'from: ', cs.getpeername())
message = 'Hello client #' + \
str(client_count) + \
' ! You are entering the number guess competion now !\n' + \
'There are currently ' + str(len(threads)) + \
' players int game.'
cs.sendall(bytes(message, 'ascii'))
players_count_message = "There are currently " + str(client_count) + \
" players in game."
while not client_guessed:
try:
cnumber = cs.recv(4)
if client_guessed:
break
cnumber = struct.unpack('!I', cnumber)[0]
if cnumber > my_num:
cs.sendall(b'S')
cs.sendall(bytes(players_count_message, 'ascii'))
if cnumber < my_num:
cs.sendall(b'H')
cs.sendall(bytes(players_count_message, 'ascii'))
if cnumber == my_num:
mylock.acquire()
client_guessed = True
winner_thread = threading.get_ident()
mylock.release()
except socket.error as msg:
print('Error:', msg.strerror)
break
if client_guessed:
if threading.get_ident() == winner_thread:
cs.sendall(b'G')
cs.sendall(bytes(players_count_message, 'ascii'))
print('We have a winner', cs.getpeername())
print("Thread ", my_idcount, " winner")
e.set()
else:
cs.sendall(b'L')
cs.sendall(bytes(players_count_message, 'ascii'))
print("Thread ", my_idcount, " looser")
time.sleep(1)
cs.close()
print("Worker Thread ", my_idcount, " end")
def reset_srv():
global mylock, client_guessed, winner_thread, my_num, threads, e, client_count
while True:
e.wait()
for thread in threads:
thread.join()
print("all threads are finished now")
e.clear()
mylock.acquire()
threads = []
client_guessed = False
winner_thread = 0
client_count = 0
my_num = random.randint(start, stop)
print('Server number: ', my_num)
mylock.release()
if __name__ == '__main__':
try:
rs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
rs.bind(('0.0.0.0', 1234))
rs.listen(5)
except socket.error as msg:
print(msg.strerror)
exit(-1)
t = threading.Thread(target=reset_srv, daemon=True)
t.start()
while True:
client_socket, addrc = rs.accept()
t = threading.Thread(target=worker, args=(client_socket,))
threads.append(t)
client_count += 1
t.start()
client.py client.py
__author__ = 'emil'
import socket
import struct
import time
if __name__ == '__main__':
try:
s = socket.create_connection(('localhost', 1234))
except socket.error as msg:
print("Error: ", msg.strerror)
exit(-1)
finished = False
data = s.recv(1024)
print(data.decode('ascii'))
step_count = 0
while not finished:
my_num = 0
while True:
try:
my_num = int(input("Enter number: "))
break
except ValueError:
print("Invalid input.")
try:
s.sendall(struct.pack('!I', my_num))
answer = s.recv(1)
message = s.recv(1024)
if answer == b'S' or answer == b'H':
print(message.decode('ascii'))
except socket.error as msg:
print('Error: ', msg.strerror)
s.close()
exit(-2)
step_count += 1
print('Sent ', my_num, ' Answer ', answer.decode('ascii'))
if answer == b'H':
sr = my_num
if answer == b'S':
er = my_num
if answer == b'G' or answer == b'L':
finished = True
time.sleep(0.25)
s.close()
if answer == b'G':
print("You won with", my_num, "in", step_count, "steps")
else:
print("You lost. Someone got it right before you!")
You create players_count_message at the first and sent it again and again! 您首先创建了players_count_message,然后一次又一次发送! Change Your server code to this:
将您的服务器代码更改为此:
def worker(cs):
.
.
.
players_count_message = "There are currently %s players in game."
while not client_guessed:
try:
.
.
.
if cnumber > my_num:
cs.sendall(b'S')
cs.sendall(bytes(players_count_message %(str(client_count)), 'ascii'))
if cnumber < my_num:
cs.sendall(b'H')
cs.sendall(bytes(players_count_message %(str(client_count)), 'ascii'))
.
.
.
Also, You must check if a players left the game, or connections closed, You must discount that variable. 另外,您必须检查玩家是否离开了游戏,或者连接是否关闭,必须对该变量进行打折。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.