How to properly connect these three processes using pipes?


 
Thread Tools Search this Thread
Top Forums Programming How to properly connect these three processes using pipes?
# 1  
Old 02-26-2012
How to properly connect these three processes using pipes?

I'm trying to properly connect three processes in order to allow inter-process communication between them. I have one process, scanner, which takes the parent's STDIN and then processes the words within the stream. If a word length is odd, it sends it to one process, if it is even, it sends it to another. These processes should take in these words via STDIN (I assume) and then output some info back to the scanner process via STDOUT. The STDOUT of even/odd should be redirected to scanner, which will then read (using read) and then output/process the words. It's an academic exercise, not a practical one. Here's what a picture of it would look like:


Image


And here's what my code looks like (with some stuff omitted):



Code:
scanner_pid = fork();
    int scannertoeven[2]; int scannertoodd[2]; int eventoscanner[2]; int oddtoscanner[2];
     pid_t even_pid, odd_pid, scanner_pid;


     //We need the scanner pid so even and odd can send signals to it
     char pidofparent[sizeof(scanner_pid)];
     sprintf(pidofparent, "%i", scanner_pid);
   
     //Scanner
     if (scanner_pid  == 0) {

          //Scanner writes to even and odd- uncommenting these screws things up
          //dup2(scannertoodd[1], STDOUT_FILENO);
          //dup2(scannertoeven[1], STDOUT_FILENO);

          close(scannertoeven[0]); close(scannertoeven[1]);
          close(eventoscanner[0]); close(eventoscanner[1]);
          close(scannertoodd[0]); close(scannertoodd[1]);
          close(oddtoscanner[0]); close(oddtoscanner[1]);

          if(execl("./scanner", "scanner", stoeven, stoodd, eventos, oddtos, NULL ) == -1) {
               printf("execl Error!");
               exit(1);
          }

          exit(0);
          
     //Even 
     } else if ((even_pid = fork()) == 0) {
          //Even reads from scanner
          dup2(scannertoeven[0], STDIN_FILENO);
          //Even writes to scanner
          dup2(eventoscanner[1], STDOUT_FILENO);

          close(scannertoeven[0]); close(scannertoeven[1]);
          close(eventoscanner[0]); close(eventoscanner[1]);
          close(scannertoodd[0]); close(scannertoodd[1]);
          close(oddtoscanner[0]); close(oddtoscanner[1]);
          
          //Execute evenodd as even
          if(execl("./evenodd", "even", pidofparent,  NULL ) == -1) {
               printf("execl Error!");
               exit(1);
          }
          exit(0);

     //Odd
     } else if ((odd_pid = fork()) == 0){
          //Odd reads from scanner
          dup2(scannertoodd[0], STDIN_FILENO);
          //Odd reads from scanner
          dup2(oddtoscanner[1], STDOUT_FILENO);

          // Not sure which ones to close
          close(scannertoeven[0]); close(scannertoeven[1]);
          close(eventoscanner[0]); close(eventoscanner[1]);
          close(scannertoodd[0]); close(scannertoodd[1]);
          close(oddtoscanner[0]); close(oddtoscanner[1]);

          if(execl("./evenodd", "odd", pidofparent,  NULL ) == -1) {
               printf("execl Error!");
               exit(1);
          } 
          exit(0);
          
     //Main
     } else {
          //Close Pipes- all of them
          close(scannertoodd[0]); close(scannertoeven[0]); close(eventoscanner[0]); close(oddtoscanner[0]);
          close(scannertoodd[1]); close(scannertoeven[1]); close(eventoscanner[1]); close(oddtoscanner[1]);

          //Wait for children to finish
          waitpid(scanner_pid, &status1, 0);
          waitpid(odd_pid, &status2, 0);
          waitpid(even_pid, &status3, 0);
          printf("\nAll processes terminated successfully\n");
     }


My problem is that I don't know how to properly use dup2 and close. Currently scanner will receive the proper stdin, but I don't think its redirecting its stdout properly. Do I need to redirect that for this, because in scanner, I write to each respective even/odd process like so (I use the file descriptors as passed to it from the main program, as demonstrated above:


Code:
//Send to odd
                    if ((length & 1) == 1) {
                         write(scannertoodd, w, (strlen(w) + 1));
                    //Send to even
                    } else {                 
                         write(scannertoeven, w, (strlen(w) + 1));


Any feedback/advice/etc would be greatly appreciated! I'm extremely close to finishing- it's just the plumbing that eludes me.
# 2  
Old 02-27-2012
You had the right idea but you're never calling pipe(). So that wouldn't work no matter what you do.

Code:
int main(void)
{
        pid_t childa, childb;
        int apipein[2], apipeout[2];
        int bpipein[2], bpipeout[2];

        pipe(apipein); pipe(apipeout);
        pipe(apipein); pipe(apipeout);

        childa=fork();
        if(childa == 0) // Child code
        {
                int n;
                dup2(apipein[0], STDIN_FILENO);
                dup2(apipeout[1], STDOUT_FILENO);

                for(n=0; n<2; n++)
                {
                        close(apipein[n]); close(apipeout[n]);
                        close(bpipein[n]); close(bpipeout[n]);
                }

                exec(...);
                exit(1); // If we get here, exec failed, therefore return error!
        }

        childb=fork();
        if(childb == 0)
        {
                dup2(bpipein[0], STDIN_FILENO);
                dup2(bpipeout[1], STDOUT_FILENO);

                for(n=0; n<2; n++)
                {
                        close(apipein[n]); close(apipeout[n]);
                        close(bpipein[n]); close(bpipeout[n]);
                }

                exec(...);
                exit(1);
        }

        // Close all ends of the pipes we're not using
        close(apipein[0]); close(bpipein[0]);
        close(apipeout[1]); close(bpipeout[1]);
}

Of course, with four sets of pipes to deal with, you're inevitably going to end up blocking if you don't use something like select() to inform you when any of them are ready to be read or written -- when reading or writing to them won't cause your program to stall. You should set them nonblocking, too.
# 3  
Old 02-27-2012
Thanks for the response. I will look over my code. I actually did call pipe in mine- I just omitted it. Mine looks like this:

Code:
int scannertoeven[2]; int scannertoodd[2]; int eventoscanner[2]; int oddtoscanner[2];
pid_t even_pid, odd_pid, scanner_pid;
if (pipe(scannertoeven) || (pipe(eventoscanner))) { fprintf(stderr, "Pipe error bewteen scanner and even!\n"); exit(1); }
if ((pipe(scannertoodd) || (pipe(oddtoscanner)))) { fprintf(stderr, "Pipe error between scanner and odd!\n"); exit(1); }

I still haven't figure it out, but when I do I'll post results! in the meantime, any help would still be greatly appreciated.
# 4  
Old 02-27-2012
How about the full-fledged example I just posted for you, something wrong with it?

I think your problems had to do with catch-22 situations though -- you waiting for process 1 to read, while process 1's waiting for you to read from it... That's why you need to use select(), since it can wait for multiple sets of descriptors at once, and tell you which of them needs to be dealt with.
# 5  
Old 02-27-2012
There's nothing wrong with your example. The problem is that I have three processes that are forked off the main process. I should have perhaps been a bit clearer specifying that. I will look into select- that might solve the trick. I do use a signal from the even/odd subprocesses to tell the scanner when it's done processing input and wants to write information. The problem is that even/odd never receives input on its standard input.
# 6  
Old 02-27-2012
Have your scanner process do that forking then, instead of main.

You could even make it its own application instead of part of main.
# 7  
Old 02-27-2012
Quote:
Originally Posted by Corona688
Have your scanner process do that forking then, instead of main.

You could even make it its own application instead of part of main.
I have scanner as its own application:
if(execl("./scanner", "scanner", stoeven, stoodd, eventos, oddtos, NULL ) == -1) { printf("execl Error!"); exit(1); }

The problem is that when scanner forks, I want to be able to write to even/odd and then receive from even/odd (so there are three distinct processes- all of the code from below is from another driver program, so I guess when I execute the driver there are four processes). Would it be better to move the even/odd forks under the scanner fork? I cannot fork inside of the scanner program (restraint given to me).
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Advanced & Expert Users

Connect direct - SFTP - List of servers that I can connect

Greetings Experts, I am working for a bank client and have a question on connect-direct and SFTP. We are using Linux RedHat servers. We use connect-direct to transfer (NDM) files from one server to another server. At times, we manually transfer the files using SFTP from one server to another... (2 Replies)
Discussion started by: chill3chee
2 Replies

2. Cybersecurity

When i start CSF i cant connect VPS or download any data into it It appears i cant connect Linux VP?

It appears i cant connect linux VPS server via SSH or i cant SCP any file to it and i cant wget any file TO it (from inside it) while CSF (Config Server Firewall, LFD is running. Just after isntall in default configuration and after changing TESTING mode to LIVE mode. Trying to wget & install... (1 Reply)
Discussion started by: postcd
1 Replies

3. AIX

AIX Remote Connect Fail With “No more multiple IP addresses to connect” Error

We have a production server at a client site running AIX. And recently when users are trying to connect to it via telnet, it prompts "No more multiple IP addresses to connect". Can I know what does this error mean? and how to rectify this? Thanks. (2 Replies)
Discussion started by: a_sim
2 Replies

4. Programming

Pipes connecting 3 processes in a "circle"

I am trying to get a better understanding of pipes and processes. I have code in which I link 3 processes A,B,C. I have A->B->C but how would I go about getting C->A? Here is my code: #include <stdio.h> #include <stdlib.h> #include <unistd.h> main() { pid_t A, B, C; int fd; int fd2; ... (1 Reply)
Discussion started by: tfarmer4
1 Replies

5. Programming

IPC between processes, pipes, etc

I need help with understanding this in C-programming style(the systemcalls only): Three processes communicates via two pipes. (when the processes creates all stdin is the keyboard and all stdout is the screen) This is how the communication goes: Process 2 stdin (keyboard) and stdout goes via... (3 Replies)
Discussion started by: oskis
3 Replies

6. Shell Programming and Scripting

Finding the age of a unix process, killing old processes, killing zombie processes

I had issues with processes locking up. This script checks for processes and kills them if they are older than a certain time. Its uses some functions you'll need to define or remove, like slog() which I use for logging, and is_running() which checks if this script is already running so you can... (0 Replies)
Discussion started by: sukerman
0 Replies

7. Shell Programming and Scripting

Multiple SQLPLUS background processes not working properly

Hi All, I am running 25 background process from a Unix shell script which calls a single Oracle procedure with different paramenters each time. These 25 process creates 25 different files. When i run these 25 Background SQLPLUS processes, few files are not created completly but if i run 25... (1 Reply)
Discussion started by: rawat_me01
1 Replies

8. Solaris

Identifying and grouping OS processes and APP processes

Hi Is there an easy way to identify and group currently running processes into OS processes and APP processes. Not all applications are installed as packages. Any free tools or scripts to do this? Many thanks. (2 Replies)
Discussion started by: wilsonee
2 Replies

9. UNIX for Advanced & Expert Users

Monitoring Processes - Killing hung processes

Is there a way to monitor certain processes and if they hang too long to kill them, but certain scripts which are expected to take a long time to let them go? Thank you Richard (4 Replies)
Discussion started by: ukndoit
4 Replies

10. Filesystems, Disks and Memory

PIPEs and Named PIPEs (FIFO) Buffer size

Hello! How I can increase or decrease predefined pipe buffer size? System FreeBSD 4.9 and RedHat Linux 9.0 Thanks! (1 Reply)
Discussion started by: Jus
1 Replies
Login or Register to Ask a Question