1

I try to make a program that request user an input and the reader function print the input without the input function blocking the reader function.

Here what i can do

import multiprocessing as mp
import time


def ProInput(queue):
    while True:
        if queue.empty():
            print("{} waiting an item".format(mp.current_process().name))
        else:
            item = queue.get()
            if(item == 'exit'):
                break;
            else:
                print("{} processing {}".format(mp.current_process().name, item))
        time.sleep(1)



def InputRead(queue):
    while True:
        f = input("Insert your input :")
        queue.put(f)
        if(f == 'exit'):
            break;
        print("You insert {} into the system".format(f))

if __name__ == '__main__':
    st = time.time()
    q = mp.Queue()

    OutputSys = mp.Process(target=ProInput, name='Reader', args=(q,))
    OutputSys.daemon = True
    OutputSys.start()

    InputRead(q)

    et = time.time()
    OutputSys.join()
    print('Total running time {}'.format(et-st))

Is that any way to make The Input function in first terminal and the Reader function in the other terminal? I mean, i can give the input without disturbed by the Reader function.My Program Looks like

FAQ

Q : Why you not delete the print function in Reader? Your problem solved!

A : I need to monitor the process in my program.

Ps. : Feel free to correct my grammar, since my English still broken.

Albert H M
  • 257
  • 2
  • 15

1 Answers1

0

Please clarify what do you mean, saying "the other terminal". Multiprocessing by itself doesn't deal with terminal (TTY/PTY) allocation or management, and it's somewhat unusual for a process to have multiple user-accessible terminals.

If I understood your question correctly, you basically want your program to be monitored (health checks). There are two common general approaches to this:

  • If all you need is to output status information somewhere, consider writing to some log (e.g. a file, syslog or some UDP socket - consider using logging module as it's very flexible). Then set up your monitoring solution will watch the log file (or listen on a socket for the new messages) and react accordingly.

    I.e. instead of print do something like this:

    import logging
    
    def setup_logger():
        # Just a very primitive example. Not a good code.
        logger = logging.getLogger("proinput")
        logger.setLevel(logging.DEBUG)
        # Or `fh = logging.StreamHandler(sys.stdout)`
        # to get the same effect as your previous print calls
        fh = logging.FileHandler("proinput.log")
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            "[%(asctime)s] %(process)d[%(processName)s] "
            "%(name)s (%(funcName)s): %(levelname)s: %(message)s"
        )
        fh.setFormatter(formatter)
        logger.addHandler(fh)
        return logger
    
    def pro_input(queue):
        logger = setup_logger()
        while True:
            ...
            logger.info("Waiting for an item")
            ...
            logger.info("Processing: %s", repr(item))
    

    The example above is very primitive, inflexible and won't scale well. Check out logging documentation (esp. the tutorials and the section on configuring logging - that's what I meant when I said that logging is flexible) and a question on using logging with multiprocessing for more information.

    This approach would also allow your "multiple terminals" case, if you really want to have two terminals. Just use a pre-created terminal device (e.g. open a new console window, run tty and it'll output something like /dev/pts/9) as an output file and pass this upon starting your program via command-line options or as environment variable.

  • Another option is to implement a special server (e.g. HTTP or simple TCP) that would allow monitoring software to connect and query for the status. The idea is to have a separate process in your program that's dedicated to provide status information to the external world.

    This is uncommon for the interactive software like yours, but for the servers this is quite a popular approach how to implement health checks. In case your software will be "headless" and user input is just for prototyping, consider checking out Prometheus. It has a nice instrumentation library that allows to easily measure and output that data over HTTP.

Which approach you choose (passively watching vs actively querying) depends on your monitoring solution and your personal preferences.

Community
  • 1
  • 1
drdaeman
  • 11,159
  • 7
  • 59
  • 104