Python - multithreaded sockets
Question: From my understanding python can only run 1 thread at a time so if I were to
do something like this

    
    
    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()
    

if I need to build the webserver part I will. But, I'll explain it. Okay, so
basically when someone connects to the websever under the mountpoint that was
set, They will get there own personal thread that then grabs the data from
`Source()` and sends it to them. Now say another person connects to the mount
point and the last client as well as the source is still going. Wouldn't the
new client be blocked from getting the Source data considering there are two
active threads?


Answer: Your understanding of how Threads work in Python seems to be incorrect, based
on the question you are asking. If used correctly, threads will not be
blocking: you can instantiate multiple thread with Python. The limitation is
that, due to the [Global Interpreter
Lock](http://www.dabeaz.com/python/UnderstandingGIL.pdf) (GIL), you cannot get
the full parallelism expected in thread programming (e.g. simultaneous
execution and thus, reduced runtime). What is going to happen in your case is
that the two threads will take, together, the same amount of time that they
would take if they were executed sequentially (although that is not
necessarily what happens in practice).

