Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

select() call still blocking after call to setblocking(False)

I have this bit of server side code:

    def listen_on_port(self):

        try:
            running = True
            HOST = ''                # Symbolic name meaning all available interfaces
            PORT = int(self.port)    # Arbitrary non-privileged port
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server_socket.bind((HOST, PORT))
            server_socket.listen()
            server_socket.setblocking(False)  # non-blocking I/O
            self.logger.info(f'listening on port {self.port}')
            read_list = [server_socket]
            while running:
               try:
                    self.logger.info(f'calling select().')
                    readable, writable, errored = select.select(read_list, [], [])
                    self.logger.info(f'called select().')
                    for s in readable:
                        if s is server_socket:
                            client_socket, address = server_socket.accept()
                            read_list.append(client_socket)
                            self.logger.info(f"Connection from address = {address} client_socket is {client_socket}.")
                        else:
                            self.logger.info(f"going to call s.recv(). s is {s}")
                            try:
                                data = s.recv(1024)
                                self.logger.info(f"Got data = {data}.")
                                if 'terminate' in data.decode('utf-8'):
                                    self.logger.info(f"terminating.")
                                    running = False
                            except Exception as ex:
                                self.logger.info(f'error s.recv() ex={ex}.')
                            finally:
                                self.logger.info(f"closing socket. s = {s}.")
                                s.close()
                                read_list.remove(s)
               except Exception as ex:
                   self.logger.info(f'Inside while True. error ex={ex}.')
                   raise ex
        except Exception as ex:
            self.logger.info(f'error ex={ex}.')

When I run my script I can see in my log file that my code waits for …

readable, writable, errored = select.select(read_list, [], [])

… to return. My log file:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

$ cat /tmp/test.log    
doing port 50050
listening on port 50050
calling select().

I am calling …

server_socket.setblocking(False)  # non-blocking I/O

… but the code still blocks. I am running on a mac (not a Linux system) if that matters.

>Solution :

select doesn’t care whether the sockets are blocking or not. If you want to make a non-blocking select call, you need to specify a timeout value of 0:

readable, writable, errored = select.select(read_list, [], [], 0)

That said, it’s not like your code has anything better to do than block. Specifying timeout=0 is just going to turn your while running loop into a busy-wait.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading