почему поток запускается только один раз? - PullRequest
0 голосов
/ 11 февраля 2020

Это мой клиент:

from tkinter import *
import tkinter.simpledialog
import socket
import select
import ssl
import threading
Host = '127.0.0.1'
Port = 87
def create_connection():
    return socket.create_connection((Host, Port))

def gui():
    global e1
    global txt
    root = Tk()
    root.title('Amifre chat')
    root.geometry("700x515")
    txt = Text(root, width=70, height=30)
    txt.config(state=DISABLED)
    e1 = Entry(root, width=93)
    e1.place(x=0, y=487)
    txt.place(x=0)
    t = threading.Thread(target=display_msg())
    t.daemon = True
    root.after(1, t.start())
    root.mainloop()

def display_msg():
    r, w, x = select.select([client_socket], [], [], 0.00001)
    if client_socket in r:
        data = client_socket.recv().decode()
        txt.config(state=NORMAL)
        txt.insert(INSERT, data + '\n')
        txt.config(state=DISABLED)

if __name__ == '__main__':
    start = Tk()
    b = Button(start, text='Click to join the chat', command=create_user_name).grid(row=0)
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    client_socket = create_connection()
    client_socket = context.wrap_socket(client_socket, server_hostname='127.0.0.1')
    start.mainloop()
    gui()

Это клиент для чата, и поток в функции gui вызывает функцию display_msg только один раз, так что кто-нибудь имеет представление, почему это так? (отправка данных работает хорошо, и она отключается в клиенте без GUI)

Ответы [ 2 ]

0 голосов
/ 12 февраля 2020

Вы должны передать только имя функции опции target и вызвать t.start() напрямую, не используя after():

t = threading.Thread(target=display_msg, daemon=True)
t.start()

Затем вам нужно использовать, пока l oop внутри display_msg() чтобы получать данные с сервера:

def display_msg():
    while True:
        r, w, x = select.select([client_socket], [], [])
        if client_socket in r:
            data = client_socket.recv(1024).decode()
            txt.config(state=NORMAL)
            txt.insert(INSERT, data + '\n')
            txt.config(state=DISABLED)
0 голосов
/ 11 февраля 2020

Этот код:

t = threading.Thread(target=display_msg())

функционально идентичен этому коду:

result = display_msg()
t = threading.Thread(result)

И этот код:

root.after(1, t.start())

функционально идентичен этому коду :

result = t.start()
root.after(1, result)

И в threading.Thread, и в after значения, данные функциям, должны быть ссылками на функцию, а не результатом function (если только результат сам по себе не является ссылкой на функцию).

t = threading.Thread(target=display_msg)
...
root.after(1, t.start)

Независимо от этого, ответ на «почему поток запускается только один раз?» заключается в том, что именно так поступают потоки. Потоки работают до тех пор, пока они не будут сделаны. Если вам нужен код для запуска в al oop, вам нужно написать l oop самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...