【问题标题】:Python: GUI and Socket Threading [closed]Python:GUI 和套接字线程 [关闭]
【发布时间】:2016-04-19 23:56:47
【问题描述】:

我正在开发一个软件并且遇到了一些主要问题(我是 python 新手)... 该应用程序应处理 .csv 文件中的一些任务。当程序启动时,它应该读取文件并在 GUI 中很好地显示任务。 GUI 中有一些工具,例如编辑、删除和移动某些任务。 还有一个正在运行的套接字服务器,它将排序的任务发送给客户端。 这两个功能都在工作,但不是并行的。 每次客户端连接到服务器时,GUI 都会崩溃。我知道发生这种情况是因为套接字阻塞了进程,我需要为 GUI 创建一个单独的线程,但我不知道该怎么做。

我将 GUI 的所有 Tkinter 代码填充到一个函数中,并尝试了 threading.Thread(target=guiStart, args=())。但随后 GUI 停止工作,因为错误消息如“从不同的公寓调用 Tcl”(在 OSX 上工作,但也应该在 Win 上运行)和修改 GUI 的函数的一些未定义的全局变量......

我不知道该怎么做,我阅读了很多线程示例代码,但我不知道如何解决我的问题。

有人可以告诉我该怎么做吗?

这是我的代码(没有我的线程尝试):

from Tkinter import *
import csv
import socket
import sys
import json
from thread import *
import threading

root = Tk()

#------------Server Config------

HOST = ''   
PORT = 8888 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #test
print 'Socket created'

#Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error as msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message: ' + msg[1]
    sys.exit()

print 'Socket bind complete'

#Start listening on socket
s.listen(10)
print 'Socket now listening'

#------------Functions---------


# a lot of functions...       


def clientthread(conn):

    conn.send('CONNECTED \n')
    #conn.send(json.dumps(tasksA))
    station = ""


    while True:
        print "Entered loop" #

        databytes = conn.recv(1024)
        if not databytes: break

        data = databytes.decode("utf-8")
        print "Client: " + data


        if data =='STATION_A':
            station = "Station A"
            print "Connected to: " + station
            conn.send(json.dumps(tasksA))

        #some more if-clauses


    conn.close()

def runServer():
    while True:
        conn, addr = s.accept()
        #conn.setblocking(0)
        print 'Connected with ' + addr[0] + ':' + str(addr[1])

        #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
        start_new_thread(clientthread ,(conn,))
        root.after(100, runServer)
    s.close()



#------------GUI-----------------------

root.geometry("1024x768")
root.minsize(width="1024", height="768")
root.title("FTS v04")

#... left out most of the gui stuff... just too much code



loadTasks()   
thread = threading.Thread(target = runServer)
thread.deamon = True
thread.start()
root.mainloop()

(还有一个我无法摆脱的小错误:see here

【问题讨论】:

  • 欢迎来到 SO。请阅读How to create a Minimal, Complete, and Verifiable example。我认为没有人愿意阅读文字墙。
  • 您是否尝试过将 GUI 代码保留在主线程中,并将套接字代码移动到单独的线程中?
  • Lafexlos,感谢您的提示。我将编辑代码! Bryan,我认为套接字会为每个客户端创建一个单独的线程......你到底是什么意思?

标签: python multithreading sockets user-interface tkinter


【解决方案1】:

我建议您查看asyncio 并使用异步套接字,而不是为每个连接生成一个新线程。这将消除从套接字读取/接受“阻塞”的所有想法。当涉及到异步文件 I/O 时,Asyncio 处理了很多棘手的事情,但需要一点时间来适应整个“未来”概念。我建议您阅读文档。

【讨论】:

  • 谢谢,但这看起来真的很复杂。你能告诉我如何在现有代码中添加这个模块吗?
  • Oasiscircle,我忘了说我必须使用 Python 2.7。没有其他办法,因为我需要使用一些不适用于 Python 3.x 的第三方模块。
  • 哦,asyncio 仅适用于 Python 3+。尝试查找“非阻塞套接字”并使用它们来消除套接字读取时的阻塞。
猜你喜欢
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 2013-05-20
相关资源
最近更新 更多