Значение захвата от бесконечной l oop на другом потоке - PullRequest
0 голосов
/ 26 марта 2020

Я создаю бота, который опирается на событие, которое в свою очередь запускает код. Основная идея заключается в том, чтобы запустить одно бесконечное l oop прослушивание определенного события, которое, в свою очередь, запускает код, который захватывает некоторую переменную из second бесконечного l oop, который обновляет информацию в потоке. Я проиллюстрировал это на изображении: click me (" function ", о которой я упоминал на этом рисунке, не обязательно должна быть функцией, это просто способ показать что я хочу)

Вот код: ( документация здесь , если вам нужно понять функции, чтобы понять проблему)

q = queue.Queue()


def main_thread(que, data, conn):
    while True:
        try:
            event = conn.wait_for_event(timeout=60) #waiting for event, when no 
                                                    #event triggers for 60 
                                                    #seconds, goes back to 'while 
                                                    #True:' and tries again
        except ts3.query.TS3TimeoutError:           #Name of the error
            pass
        else:
            print("event triggered")
            q.mutex.acquire()                       #Queue library [documentation here][3]
            public_channels = que.get_nowait()
            q.mutex.release()


t1 = Thread(target=main_thread, args=(q, data, conn)) #Starting main_thread that will listen
t1.start()                                            #to an event



while True:                                           #infinite loop that refreshes
                                                      #value of publicchannels 
    publicchannels = list(map(lambda y: (y['cid'], y['total_clients']), 
list(filter(lambda x: x['pid'] in data['settings']['parent_public_channels'], 
conn.exec_('channellist'))))) 

#This part /\ maps channels' current client to its IDs, with current config output is:
[('71', '1'), ('72', '1'), ('73', '0'), ('75', '0'), ('76', '0'), ('77', '0'),
#('79', '0'), ('80', '0'), ('81', '0'), ('83', '0'), ('84', '0'), ('85', '0')]

    time.sleep(1)
    q.mutex.acquire()
    q.put(publicchannels)
    q.mutex.release()

А вот конфиг:

{
  "interface": {
    "uri": "telnet://ip:10011",
    "username": "serveradmin",
    "password": "pass",
    "port": "9987",
    "nickname": "#name",
    "default_channel": null
  },
  "settings": {
    "parent_public_channels": [
      "70",
      "74",
      "78",
      "82"
  ],
  "permit_channel_group": 31,
  "guest_channel_group": 12
  }
}

Ошибка, которую я получаю, но программа все еще работает:

Failed to decode the value part properly: ''utf-8' codec can't decode byte 0x90 in position 11: invalid start byte'.
Failed to decode the value part properly: ''utf-8' codec can't decode bytes in position 37-38: invalid continuation byte'.

позиции байтов кажутся случайными при каждом запуске программы, также это не дает эти ошибки иногда

Ошибка, которая останавливает программу:

Traceback (most recent call last):
  File "C:/Users/jasiu/Desktop/kickPermission/main.py", line 91, in <module>
    publicchannels = list(map(lambda y: (y['cid'], y['total_clients']), list(filter(lambda x: x['pid'] in data['settings']['parent_public_channels'], ts3conn.exec_('channellist')))))
  File "C:/Users/jasiu/Desktop/kickPermission/main.py", line 91, in <lambda>
    publicchannels = list(map(lambda y: (y['cid'], y['total_clients']), list(filter(lambda x: x['pid'] in data['settings']['parent_public_channels'], ts3conn.exec_('channellist')))))
KeyError: 'pid'

, когда я использую только list(map(lambda y: (y['cid'], y['total_clients']), list(filter(lambda x: x['pid'] in data['settings']['parent_public_channels'], ts3conn.exec_('channellist'))))) при попытке его напечатать, ошибки нет

Если вы не знаете, как мне помочь, вы также можете дать мне несколько советов о том, как получить какое-то значение из бесконечного l oop, которое находится в потоке для другого, пока l oop , Если у вас есть какие-либо другие идеи, как вы могли бы сделать это (рисунок-изображение), пожалуйста, по крайней мере, прокомментируйте.

РЕДАКТИРОВАТЬ: Я провел некоторый тест с этим кодом, и я предполагаю, что это проблема, связанная с безопасностью потока, потому что метод (я сделал тесты) conn.query ("channellist"). all () всегда должен выдавать одно и то же значение, но вместо этого иногда дает то, что никогда не должно быть вывод и иногда он смешивает этот невидимый вывод с ожидаемым выводом, что, в свою очередь, дает «KeyError».

...