Running a C++ compiled program in the background and sending input whenever needed

5,495

Solution 1

This is awkward and inconvenient, but possibly less so than the other answers:

Every time your program asks for input:

  1. Get to a shell prompt — and I mean the shell that launched your program.  (I.e., the fact that you're not just running your "engine" program in the foreground suggests that you're using the terminal for something else, like maybe editing files.  Every time your program asks for input, you'll need to save and quit out of the editor, and get back to your primary shell.  Or you may be able to suspend the editor; but that makes the next step more complicated.)
  2. Type fg (followed by Enter, of course) to bring your background job into the foreground.  If you have multiple background jobs (as suggested above), do what you need to do to bring your "engine" program into the foreground.
  3. Interact with the program.
  4. When it's ready to resume running (computing, etc.) for a while, press Ctrl+Z, and then bg (followed by Enter).

Repeat the above as long as the program runs.

Solution 2

Unlikely that is possible. In such cases typically you need to listen network port, accept() connection and read from it data, and do whatevet you need. Then you need some client app also to send data. This is how background apps typically work.

Share:
5,495

Related videos on Youtube

stock username
Author by

stock username

Updated on September 18, 2022

Comments

  • stock username
    stock username over 1 year

    I have a compiled program written in C++ for a UNIX environment which has this kind of structure:

    int main(){
    ...
    LoadEngine()
    ...
    while(1){
        std::cin >> buffer;
        ...
        ExecuteFunction(buffer);
    }
    }
    

    Loading the engine takes quite a while, so I'm trying to start the program in the background first, then send the input whenever I need to.

    Running the program with the standard ampersand appended at the end seemingly does not make the program run in the background, but rather halts at std::cin until an input is received from the console, and stops after an input is accepted from the console.

    How do I execute the program such that the program runs continuously in the background and receive input and execute the function whenever it is needed?

    EDIT: The final product is a small device (RaspberryPi) which recognizes speech, and does something based on the words recognized. The program that I have is the part where the device does something based on the word input, and the word input corresponds to the variable buffer from the code snippet above.

    So the std::cin part is a dummy line code that I'm using for testing out that my part of the code starts up in the background process (to load the engine) and does whatever it is designed to do.

    EDIT 2 : To clarify what I’m trying to achieve, the program takes an input from a speech recognizer and does things (e.g. synthesize speech from input, send out signals to LEDs, etc.). The text input can be taken directly from the console (which my code is currently doing), or some other method that I’m not knowledgeable in. The only thing that the input adheres to is that it must be a text, and is sent from another program that recognizes speech (which is handled by some other developer). So the exact method isn’t specified. All I have to worry about is my side of the program, which executes a function from a text input (i.e. buffer from the code snippet). So the general structure would look something like this:

    Int main(){
    LoadEngine()
    while(1){
        buffer = ReceiveInput();
        ExecuteFunction(buffer);
     }}
    

    Where the ReceiveInput() part is currently implemented as std::cin. It really can be any method, as long as the engine is loaded once in the beginning, and the program is able to perform ExecuteFunction from an input until the device is turned off.

    • Scott - Слава Україні
      Scott - Слава Україні over 8 years
      The std::cin part is a dummy line code that I’m using for testing …  the program … halts at std::cin until an input is received from the console …  WHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT?  Your program is failing because of a line of code that’s there only for testing?  Why don’t you just take it out?  What you are saying doesn’t make any sense to me.  Please try to explain this better (in the question, as much as is practical).  How do you expect your program to get audio input (from the microphone, presumably)?  Are you running your program with stdin redirected, or piping something into it?
    • stock username
      stock username over 8 years
      @Scott Sorry for the confusion. I'm in charge of a small part of a bigger project, and because of my mediocrity with unix environments, the other developers suggested that I modify the program to be able to handle a text input, and they will adjust their code to synchronize with mine. So the code isn't strictly confined to std::cin; it's the only function that I could think of.
    • Scott - Слава Україні
      Scott - Слава Україні over 8 years
      Well, I still don't understand.  If the other developers suggested that you modify your program to be able to handle text input, and they promised to adjust their code to synchronize with yours, does that mean that, when everything is integrated, their program will be piped into yours?  If so, then you should test your program with input coming from a pipe.
    • stock username
      stock username over 8 years
      @Scott Yes, I think that's sort of the direction that this is going. How do I add a function in the while loop that accepts input from a pipe?
    • Scott - Слава Україні
      Scott - Слава Україні over 8 years
      When everything is tested and integrated, the final command line for the system will be something like their_program | your_program &.  Since the pipe (from their program) is now the standard input (stdin) to your program, the code you have now to read from std::cin should work, unchanged.  Test with your_testscript | your_program &, where your test script does things like sleep 600, echo "The quick brown fox ...", sleep 420, echo "jumps over the lazy dog.", ...
  • Peter Cordes
    Peter Cordes over 8 years
    A background process reading from its controlling tty automatically receives SIGTTIN, which exists for the purpose of stopping bg programs that try to read from the terminal. So yes, make a daemon and a client, like emacsclient. The client can start the daemon if not already running, so the user doesn't have to care about it. See gnu.org/software/libc/manual/html_node/Job-Control-Signals.h‌​tml for details on SIGTTIN.
  • stock username
    stock username over 8 years
    @PeterCordes I'm relateively new to daemons so I may be blatantly wrong. Aren't daemons a type of process which can't handle direct input from the console? If so, then how would I go about structuring the whole program? The engine part and the function that needs to be executed share a lot of the classes and functions, so separating them wouldn't be so efficient, nearly impossible.
  • stock username
    stock username over 8 years
    The catch is that there won't be anyone handling the console. It's a small program that's going on a Raspberry Pi. It recognizes speech and does something based on what's recognized. The program that I have is the part where the device reacts to the recognized word input (where the recognized word input is the buffer variable from the sample snippet above).
  • Peter Cordes
    Peter Cordes over 8 years
    @5422time: Instead of doing I/O to/from the terminal, the daemon would do I/O to a client that connected to it. You can have the same program be able to act as a daemon or a client. If it starts up and detects that no daemon is running, it forks. The forked process daemonizes itself (closes stdin/stdout/stderr), then makes a Unix socket like /tmp/myprog-uid$UID.sock. The "client" part only has to send data to the daemon, and print the result on the terminal, so it can be a separate simple program.
  • Peter Cordes
    Peter Cordes over 8 years
    Look at how emacsclient -c --alternate-editor= works. It starts emacs if needed, otherwise starts a new frame for the existing emacs.
  • Scott - Слава Україні
    Scott - Слава Україні over 8 years
    Your comment to Peter asks, “Aren’t daemons a type of process that can’t handle direct input from the console?”  So, do you want/need your program to be able to read from the console, or don’t you?