开发者

child waiting for another child

开发者 https://www.devze.com 2023-03-02 02:25 出处:网络
is there a way for a forked child开发者_开发问答 to examine another forked child so that, if the other forked child takes more time than usual to perform its chores, the first child may perform predef

is there a way for a forked child开发者_开发问答 to examine another forked child so that, if the other forked child takes more time than usual to perform its chores, the first child may perform predefined steps? if so, sample code will be greatly appreciated.


Yes. Simply fork the process to be watched, from the process to watch it.

if (fork() == 0) {
    // we are the watcher
    pid_t watchee_pid = fork();
    if (watchee_pid != 0) {
        // wait and/or handle timeout
        int status;
        waitpid(watchee_pid, &status, WNOHANG);
    } else {
        // we're being watched. do stuff
    }
} else {
    // original process
}

To emphasise: There are 3 processes. The original, the watcher process (that handles timeout etc.) and the actual watched process.


To do this, you'll need to use some form of IPC, and named shared memory segments makes perfect sense here. Your first child could read a value in a named segment which the other child will set once it has completed it's work. Your first child could set a time out and once that time out expires, check for the value - if the value is not set, then do what you need to do.

The code can vary greatly depending on C or C++, you need to select which. If C++, you can use boost::interprocess for this - which has lots of examples of shared memory usage. If C, then you'll have to put this together using native calls for your OS - again this should be fairly straightforward - start at shmget()


This is some orientative code that could help you to solve the problem in a Linux environment.

  pid_t pid = fork();

  if (pid == -1) {
    printf("fork: %s", strerror(errno));
    exit(1);
  } else if (pid > 0) {
    /* parent process */
    int i = 0;
    int secs = 60; /* 60 secs for the process to finish */
    while(1) {
        /* check if process with pid exists */
        if (exist(pid) && i > secs) {
          /* do something accordingly */
        }
        sleep(1);
        i++;
    }
  } else {
    /* child process */
    /* child logic here */
    exit(0);
  }

... those 60 seconds are not very strict. you could better use a timer if you want more strict timing measurement. But if your system doesn't need critical real time processing should be just fine like this.

exist(pid) refers to a function that you should have code that looks into proc/pid where pid is the process id of the child process.

Optionally, you can implement the function exist(pid) using other libraries designed to extract information from the /proc directory like procps


The only processes you can wait on are your own direct child processes - not siblings, not your parent, not grandchildren, etc. Depending on your program's needs, Matt's solution may work for you. If not, here are some other alternatives:

  • Forget about waiting and use another form of IPC. For robustness, it needs to be something where unexpected termination of the process you're waiting on results in your receiving an event. The best one I can think of is opening a pipe which both processes share, and giving the writing end of the pipe to the process you want to wait for (make sure no other processes keep the writing end open!). When the process holding the writing end terminates, it will be closed, and the reading end will then indicate EOF (read will block on it until the writing end is closed, then return a zero-length read).

  • Forget about IPC and use threads. One advantage of threads is that the atomicity of a "process" is preserved. It's impossible for individual threads to be killed or otherwise terminate outside of the control of your program, so you don't have to worry about race conditions with process ids and shared resource allocation in the system-global namespace (IPC objects, filenames, sockets, etc.). All synchronization primitives exist purely within your process's address space.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号