Skip to main content
 首页 » 编程设计

Python之多线程套接字

2024年10月24日29myhome

根据我的理解,python 一次只能运行 1 个线程,所以如果我要执行这样的操作

import socket, select 
from threading import Thread 
import config 
 
class Source(Thread): 
    def __init__(self): 
        self._wait = False 
        self._host = (config.HOST, config.PORT + 1) 
        self._socket = socket.socket() 
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
        self._sock = None 
        self._connections = [] 
        self._mount = "None" 
        self._writers = [] 
        self._createServer() 
        Thread.__init__(self) 
 
    def _createServer(self): 
        self._socket.bind(self._host) 
        self._socket.listen(2) 
        self._connections.append(self._socket) 
        self._audioPackets=[] 
 
    def _addPacket(self, packet): 
        self._audioPackets.append(packet) 
 
    def _removePacket(self, packet): 
        self._audioPackets.remove(packet) 
 
    def _getPacket(self): 
        if len(self._audioPackets) > 0: 
            return self._audioPackets[0] 
        else: 
            return None 
 
    def _sendOK(self, sock): 
        sock.send("OK") 
 
    def _sendDenied(self, sock): 
        sock.send("DENIED") 
 
    def _sendMount(self, sock): 
        sock.send("mount:{0}".format(self._mount)) 
 
    def _sendBufPacket(self, sock, packet): 
        packet = "buffer:%s" % packet 
        sock.send(packet) 
 
    def recv(self, sock, data): 
        data = data.split(":", 1) 
        if data[0] == "WAIT": self._wait = True 
        elif data[0] == "STOP_WAITING": self._wait = False 
        elif data[0] == "LOGIN": 
            if data[1] == config.SOURCE_AUTH: 
                self._source = sock 
                self._sendOK(sock) 
            else: 
                self._sendClose(sock) 
        elif data[0] == "MOUNT": 
            if self._source == sock: 
                self._mount = data[1] 
            else: 
                self._sendClose(sock) 
 
        elif data[0] == "CLIENT": 
            self._sendMount(sock) 
            self._writers.append(sock) 
 
 
    def _sendCloseAll(self): 
        for sock in self._connections: 
            sock.send("CLOSE") 
            sock.close() 
 
    def _sendClose(self, sock): 
        sock.send("CLOSE") 
        sock.close() 
 
    def main(self): 
        while True: 
            rl, wl, xl = select.select(self._connections, self._writers, [], 0.2) 
            for sock in rl: 
                if sock == self._socket: 
                    con, ip = sock.accept() 
                    self._connections.append(con) 
                else: 
                    data = sock.recv(config.BUFFER) 
                    if data: 
                        self.recv(sock, data) 
                    else: 
                        if sock in self._writers: 
                            self._writers.remove(sock) 
                        if sock in self._connections: 
                            self._connections.remove(sock) 
            for sock in wl: 
                packet = self._getPacket() 
                if packet != None: 
                    self._sendBufPacket(sock, packet) 
 
    def run(self): 
        self.main() 
 
class writeThread(Thread): 
      def __init__(self): 
          self.running = False 
 
      def make(self, client): 
          self.client = client 
          self.running = True 
 
      def run(self): 
          host = (config.HOST, config.PORT+1) 
          sock = socket.socket() 
          sock.connect(host) 
          sock.send("CLIENT") 
          sock.send("MOUNT:mountpoint") 
          while self.running: 
              data = sock.recv(config.BUFFER) 
              if data: 
                  data = data.split(":", 1) 
                  if data[0] == "buffer": 
                     self.client.send(data[1]) 
                  elif data[0] == "CLOSE": 
                       self.client.close() 
                       break 
 
 
if __name__=="__main__": 
    source = Source() 
    source.start() 
    webserver = WebServer() 
    webserver.runloop() 

如果我需要构建网络服务器部分,我会的。但是,我会解释的。 好的,所以基本上当有人在设置的挂载点下连接到网络服务器时,他们将到达那里自己的个人线程,然后从 Source() 获取数据并将其发送给他们。现在假设另一个人连接到挂载点,最后一个客户端以及源仍在运行。考虑到有两个事件线程,新客户端是否会被阻止获取源数据?

请您参考如下方法:

根据您提出的问题,您对线程在 Python 中的工作方式的理解似乎不正确。如果使用正确,线程将不会阻塞:您可以使用 Python 实例化多个线程。限制是,由于 Global Interpreter Lock (GIL),您无法获得线程编程中预期的完全并行性(例如,同时执行,从而减少运行时间)。 在您的情况下,这两个线程将共同花费与按顺序执行它们所花费的时间相同的时间(尽管这在实践中不一定会发生)。