На этом сайте есть несколько тем, касающихся этой же ошибки, но я не нашел ничего, что решило бы мою проблему.
Я работаю в Python 3 на клиенте чата, используя UDP en, и я «вручную» прикрепляю порядковые номера к каждому исходящему сообщению. Затем это сообщение сохраняется в глобальном словаре timed_msgs
, где оно имеет следующий формат { SEQNR: [MESSAGE, TIMESTAMP] }
, например, { 1: [ 'Hello', 1584443275.6280255] }
. Если клиент не получает подтверждение, соответствующее порядковому номеру, в течение двух секунд, сообщение повторно отправляется и удаляется из словаря. Если подтверждение получено, он добавляется в глобальный список целых чисел rcvd_acks
. В функции manage_timed_msgs
код выполняется по этому списку и проверяет, есть ли какие-либо сообщения, которые соответствуют полученным подтверждениям.
Теперь этот глобальный timed_msgs
можно изменить с помощью входящего подтверждения или тайм-аута. (упомянутые две секунды). Но это вызывает проблему, так как может выполнить итерацию sh, если это будет сделано, в то время как третий for-l oop проходит по ней. Код:
def manage_timed_msgs(conn: Connection):
global timed_msgs
global rcvd_acks
while True:
delete_acks = []
for i in range(0,len(rcvd_acks)):
try:
del timed_msgs[rcvd_acks[i]]
delete_acks.append(i)
except:
pass
for i in range(0,len(delete_acks)):
remove_item_number = delete_acks[-(i+1)]
del rcvd_acks[remove_item_number]
current_time = time.time()
delete_keys = []
for key in timed_msgs:
if (current_time - timed_msgs[key][1]) > 2:
req_send(conn, timed_msgs[key][0])
delete_keys.append(key)
for key in delete_keys:
del timed_msgs[key]
Если произойдет сбой, он выдаст следующую ошибку: RuntimeError: dictionary changed size during iteration
и укажет на строку for key in timed_msgs:
.
Теперь я прочитал, что можно сделать копия словаря и вместо этого l oop. Мой план состоял в том, чтобы сделать это, а затем проверить в глобальном масштабе, поступили ли какие-либо новые сообщения, и объединить два (исключая те, которые были удалены в копии, поскольку они либо повторно отправляются, либо подтверждаются). Но в этом я терплю неудачу раз за разом. Любые предложения приветствуются.