Pergunta

So I've been working on code for my OS class, and in my project, I have to create a new child process for each file on the command line, and pipe information from the child to the parent. We're supposed to be re-creating Unix's wc utility (I've handled this part already).

What I've tried thus far is:

            for(i=0; i<argcount; i++){
                    int pid;
                    pid = fork();
                    if(pid == 0){
                            /* Child Process */
                            /* Close read pipes */
                            close(l_pipe[0]);
                            close(w_pipe[0]);
                            close(c_pipe[0]);
                            wc(lflag, wflag, cflag, filenames[i]);
                    } else {
                            /* Parent Process for piping */
                            /* Close write pipes */
                            close(l_pipe[1]);
                            close(w_pipe[1]);
                            close(c_pipe[1]);

                            /* Read from pipes */
                            read(l_pipe[0], &buffer, sizeof(count_t));
                            lines+=buffer;

                            read(w_pipe[0], &buffer, sizeof(count_t));
                            words+=buffer;

                            read(c_pipe[0], &buffer, sizeof(count_t));
                            bytes+=buffer;
                    }
            }

However, this creates as many parents as there are children, which is obviously wrong. I'm not exactly sure where I should be forking. I have to use a pipeline between the child and parent processes, and I'm certain that the parent needs to read() as many times as the child write()s.

Thank you for any suggestions you can provide.

Foi útil?

Solução

As well as the issues raised by Greg Hewgill in his answer, I observe the following issues:

  1. You could have the loop fork and run the child processes, while the parent part simply goes back to the next iteration of the loop.
  2. You would then have a loop to read from the pipes.
  3. Before that loop, the parent process would close the write ends of all three pipes (otherwise it will never see EOF on the pipes).
  4. The loop to read from the pipes should read from each pipe in turn, rather than draining each pipe in turn.
  5. I'm assuming that you have count_t buffer; — it helps to show variable declarations. If you have some sort of char buffer[sizeof(count_t)] instead, then you have all sorts of problems, large and small.
  6. When the second child is created in your current scheme, the write ends of the pipes are all closed, so the second and subsequent children will be unable to send anything to the parent. You must move the three calls to close the write ends of the pipes so it is outside the loop.
  7. Your pipes must be in global variables so that the wc function can use them. This isn't the end of the world, but it is often neater to avoid global variables. This is a second-order problem; you have other more major problems to fix first.
  8. If you need to associate sizes with individual files, you have more bookkeeping to do. At the moment, you only aggregate grand totals. In that case, your current synchronous design is likely appropriate. Failing that, you'd have the children write a PID or another ID number plus the count on the pipe in one operation (to ensure the operation is atomic). Individual write operations are not interleaved unless they're too big for the pipe's internal buffer, which won't be a problem for a couple of integers.

Outras dicas

There's a couple of things I notice straight away.

  • In your child process branch, you're not calling _exit() after wc(). This means that your child process will loop around and start forking itself for further children.

  • In your parent process branch, you are waiting for the response from the child you just spawned before proceeding to create the next child. So essentially you've serialised the process and won't take advantage of multiple processes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top