<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run():
 # pylint: disable=too-many-branches """ Main thread runner for all Duts. :return: Nothing """

        Dut._logger.debug("Start DUT communication", extra={'type': '<->'})
        while Dut._run:
            Dut._sem.acquire()
            try:
                dut = Dut._signalled_duts.pop()
                # Check for pending requests
                if dut.waiting_for_response is not None:
                    item = dut.waiting_for_response
                    # pylint: disable=protected-access
                    dut.response_coming_in = dut._read_response()
                    if dut.response_coming_in is None:
                        # Continue to next node
                        continue
                    if isinstance(dut.response_coming_in, CliResponse):
                        dut.response_coming_in.set_response_time(item.get_timedelta(dut.get_time()))
                    dut.waiting_for_response = None
                    dut.logger.debug("Got response", extra={'type': '<->'})
                    dut.response_received.set()
                    continue

                # Check for new Request
                if dut.query is not None:
                    item = dut.query
                    dut.query = None
                    dut.logger.info(item.cmd, extra={'type': '-->'})
                    try:
                        dut.writeline(item.cmd)
                    except RuntimeError:
                        dut.response_coming_in = -1
                        dut.response_received.set()
                        continue
                    dut.prev = item # Save previous command for logging purposes
                    if item.wait:
                        # Only caller will care if this was asynchronous.
                        dut.waiting_for_response = item
                    else:
                        dut.query_timeout = 0
                        dut.response_received.set()
                    continue

                try:
                    line = dut.readline()
                except RuntimeError:
                    dut.response_coming_in = -1
                    dut.response_received.set()
                    continue
                if line:
                    if dut.store_traces:
                        dut.traces.append(line)
                    EventObject(EventTypes.DUT_LINE_RECEIVED, dut, line)
                    retcode = dut.check_retcode(line)
                    if retcode is not None:
                        dut.logger.warning("unrequested retcode", extra={'type': '!<-'})
                    dut.logger.debug(line, extra={'type': '<<<'})

            except IndexError:
                pass
        Dut._logger.debug("End DUT communication", extra={'type': '<->'})