Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7785059
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T20:11:42+00:00 2026-06-01T20:11:42+00:00

I need to pass messages to CLI PHP processes via stdin from Java. I’d

  • 0

I need to pass messages to CLI PHP processes via stdin from Java. I’d like to keep about 20 PHP processes running in a pool, such that when I pass a message to the pool, it sends each message to a separate thread, keeping a queue of messages to be delivered. I’d like these PHP processes to stay alive as long as possible, bringing up a new one if one dies. I looked at doing this with a static thread pool, but it seems more designed for tasks that execute and simply die. How could I do this, with a simple interface to pass a message to the pool? Will I have to implement my own custom “thread pool”?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T20:11:43+00:00Added an answer on June 1, 2026 at 8:11 pm

    I am providing some code with this as I think it will make things clearer. Basically you need to keep an pool of process objects around. Be considerate that each of these processes has a input, output and error stream you need to manage in some way. In my example I just redirect the error and output to the main processes console. You can setup callbacks and handlers to obtain the output of the PHP program if needed. If you are just processing tasks and don’t care what PHP says then leave it as is or redirect to a file.

    I am using the Apache Commons Pool library for the ObjectPool. No need to reinvent one.

    You’ll have a pool of 20 processes that run your PHP program. This alone will not get you what you need. You might want to process tasks against all 20 of these processes “at the same time.” So you’ll also need a ThreadPool that will pull a Process from your ObjectPool.

    You’ll also need to understand that if you kill, or CTRL-C your Java process the init process will take over your php processes and they will just sit there. You’ll probably want to keep a log of all the pid’s of the PHP processes you spawn, and then clean them up if you re-run your Java program.

    public class StackOverflow_10037379 {
    
        private static Logger sLogger = Logger.getLogger(StackOverflow_10037379.class.getName());
    
        public static class CLIPoolableObjectFactory extends BasePoolableObjectFactory<Process> {
    
            private String mProcessToRun;
    
            public CLIPoolableObjectFactory(String processToRun) {
                mProcessToRun = processToRun;
            }
    
            @Override
            public Process makeObject() throws Exception {
                ProcessBuilder builder = new ProcessBuilder();
                builder.redirectError(Redirect.INHERIT);
                // I am being lazy, but really the InputStream is where
                // you can get any output of the PHP Process. This setting
                // will make it output to the current processes console.
                builder.redirectOutput(Redirect.INHERIT);
                builder.redirectInput(Redirect.PIPE);
                builder.command(mProcessToRun);
                return builder.start();
            }
    
            @Override
            public boolean validateObject(Process process) {
                try {
                    process.exitValue();
                    return false;
                } catch (IllegalThreadStateException ex) {
                    return true;
                }
            }
    
            @Override
            public void destroyObject(Process process) throws Exception {
                // If PHP has a way to stop it, do that instead of destroy
                process.destroy();
            }
    
            @Override
            public void passivateObject(Process process) throws Exception {
                // Should really try to read from the InputStream of the Process
                // to prevent lock-ups if Rediret.INHERIT is not used.
            }
        }
    
        public static class CLIWorkItem implements Runnable {
    
            private ObjectPool<Process> mPool;
            private String mWork;
    
            public CLIWorkItem(ObjectPool<Process> pool, String work) {
                mPool = pool;
                mWork = work;
            }
    
            @Override
            public void run() {
                Process workProcess = null;
                try {
                    workProcess = mPool.borrowObject();
                    OutputStream os = workProcess.getOutputStream();
                    os.write(mWork.getBytes(Charset.forName("UTF-8")));
                    os.flush();
                    // Because of the INHERIT rule with the output stream
                    // the console stream overwrites itself. REMOVE THIS in production.
                    Thread.sleep(100);
                } catch (Exception ex) {
                    sLogger.log(Level.SEVERE, null, ex);
                } finally {
                    if (workProcess != null) {
                        try {
                            // Seriously.. so many exceptions.
                            mPool.returnObject(workProcess);
                        } catch (Exception ex) {
                            sLogger.log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
    
            // Change the 5 to 20 in your case. 
            // Also change mock_php.exe to /usr/bin/php or wherever.
            ObjectPool<Process> pool =
                    new GenericObjectPool<>(
                    new CLIPoolableObjectFactory("mock_php.exe"), 5);         
    
            // This will only allow you to queue 100 work items at a time. I would suspect
            // that if you only want 20 PHP processes running at a time and this queue
            // filled up you'll need to implement some other strategy as you are doing
            // more work than PHP can keep up with. You'll need to block at some point
            // or throw work away.
            BlockingQueue<Runnable> queue = 
                new ArrayBlockingQueue<>(100, true);
    
            ThreadPoolExecutor executor = 
                new ThreadPoolExecutor(20, 20, 1, TimeUnit.HOURS, queue);
    
            // print some stuff out.
            executor.execute(new CLIWorkItem(pool, "Message 1\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 2\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 3\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 4\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 5\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 6\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 7\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 8\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 9\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 10\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 11\r\n"));
    
            executor.shutdown();
            executor.awaitTermination(4000, TimeUnit.HOURS);
    
            pool.close();        
        }
    }
    

    Output of Program Run:

    12172 - Message 2
    10568 - Message 1
    4804 - Message 3
    11916 - Message 4
    11116 - Message 5
    12172 - Message 6
    4804 - Message 7
    10568 - Message 8
    11916 - Message 9
    11116 - Message 10
    12172 - Message 11
    

    Code of C++ program to just output what was input:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    int main(int argc, char* argv[])
    {
        DWORD pid = GetCurrentProcessId();
        std::string line;
        while (true) {      
            std::getline (std::cin, line);
            std::cout << pid << " - " << line << std::endl;
        }
    
        return 0;
    }
    

    Update

    Sorry for the delay. Here is a JDK 6 version for anyone interested. You’ll have to run a separate thread to read all the input from the InputStream of the process. I’ve set this code up to spawn a new thread along side each new process. That thread always read from the process as long as it is alive. Instead of outputting directly to a file I set it up such that it uses the Logging framework. That way you can setup a logging configuration to go to a file, roll over, go to console etc. without it being hard coded to go to a file.

    You’ll notice I only start a single Gobbler for each process even though a Process has stdout and stderr. I redirect stderr to stdout just to make things easier. Apparently jdk6 only supports this type of redirect.

    public class StackOverflow_10037379_jdk6 {
    
        private static Logger sLogger = Logger.getLogger(StackOverflow_10037379_jdk6.class.getName());
    
        // Shamelessy taken from Google and modified. 
        // I don't know who the original Author is.
        public static class StreamGobbler extends Thread {
    
            InputStream is;
            Logger logger;
            Level level;
    
            StreamGobbler(String logName, Level level, InputStream is) {
                this.is = is;
                this.logger = Logger.getLogger(logName);
                this.level = level;
            }
    
            public void run() {
                try {
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        logger.log(level, line);
                    }
                } catch (IOException ex) {
                    logger.log(Level.SEVERE, "Failed to read from Process.", ex);
                }
                logger.log(
                        Level.INFO, 
                        String.format("Exiting Gobbler for %s.", logger.getName()));
            }
        }
    
        public static class CLIPoolableObjectFactory extends BasePoolableObjectFactory<Process> {
    
            private String mProcessToRun;
    
            public CLIPoolableObjectFactory(String processToRun) {
                mProcessToRun = processToRun;
            }
    
            @Override
            public Process makeObject() throws Exception {
                ProcessBuilder builder = new ProcessBuilder();
                builder.redirectErrorStream(true);
                builder.command(mProcessToRun);
                Process process = builder.start();
                StreamGobbler loggingGobbler =
                        new StreamGobbler(
                        String.format("process.%s", process.hashCode()),
                        Level.INFO,
                        process.getInputStream());
                loggingGobbler.start();
                return process;
            }
    
            @Override
            public boolean validateObject(Process process) {
                try {
                    process.exitValue();
                    return false;
                } catch (IllegalThreadStateException ex) {
                    return true;
                }
            }
    
            @Override
            public void destroyObject(Process process) throws Exception {
                // If PHP has a way to stop it, do that instead of destroy
                process.destroy();
            }
    
            @Override
            public void passivateObject(Process process) throws Exception {
                // Should really try to read from the InputStream of the Process
                // to prevent lock-ups if Rediret.INHERIT is not used.
            }
        }
    
        public static class CLIWorkItem implements Runnable {
    
            private ObjectPool<Process> mPool;
            private String mWork;
    
            public CLIWorkItem(ObjectPool<Process> pool, String work) {
                mPool = pool;
                mWork = work;
            }
    
            @Override
            public void run() {
                Process workProcess = null;
                try {
                    workProcess = mPool.borrowObject();
                    OutputStream os = workProcess.getOutputStream();
                    os.write(mWork.getBytes(Charset.forName("UTF-8")));
                    os.flush();
                    // Because of the INHERIT rule with the output stream
                    // the console stream overwrites itself. REMOVE THIS in production.
                    Thread.sleep(100);
                } catch (Exception ex) {
                    sLogger.log(Level.SEVERE, null, ex);
                } finally {
                    if (workProcess != null) {
                        try {
                            // Seriously.. so many exceptions.
                            mPool.returnObject(workProcess);
                        } catch (Exception ex) {
                            sLogger.log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
    
            // Change the 5 to 20 in your case. 
            ObjectPool<Process> pool =
                    new GenericObjectPool<Process>(
                    new CLIPoolableObjectFactory("mock_php.exe"), 5);
    
            BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100, true);
    
            ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 20, 1, TimeUnit.HOURS, queue);
    
            // print some stuff out.
            executor.execute(new CLIWorkItem(pool, "Message 1\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 2\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 3\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 4\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 5\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 6\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 7\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 8\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 9\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 10\r\n"));
            executor.execute(new CLIWorkItem(pool, "Message 11\r\n"));
    
            executor.shutdown();
            executor.awaitTermination(4000, TimeUnit.HOURS);
    
            pool.close();
        }
    }
    

    Output

    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 9440 - Message 3
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 8776 - Message 2
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 6100 - Message 1
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 10096 - Message 4
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 8868 - Message 5
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 8868 - Message 8
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 6100 - Message 10
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 8776 - Message 9
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 10096 - Message 6
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 9440 - Message 7
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: 6100 - Message 11
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: Exiting Gobbler for process.295131993.
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: Exiting Gobbler for process.756434719.
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: Exiting Gobbler for process.332711452.
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: Exiting Gobbler for process.1981440623.
    Apr 11, 2012 8:41:02 PM stackoverflow.StackOverflow_10037379_jdk6$StreamGobbler run
    INFO: Exiting Gobbler for process.1043636732.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to pass messages to my C program from PHP and I am
I need to pass an array from JavaScript to a page method in C#.
I wrote a Java application that reads and sends SMS messages from a USB
I need to pass the response from ajax call to a jquery template.The response
I need to pass HTML code to messages and am doing so using templates.
I have a need to send messages (requests from the User to the Engine,
I am working on app where I need to pass messages between a C++
I need to pass achieve section to every pages of my blog. From Google,
I am receiving messages from the network on a non-GUI thread and need to
I need to pass all my current page cookies to other server with request:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.