LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-07-2013, 10:05 AM   #1
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Rep: Reputation: Disabled
Question fork and pipes


hi..

i want to make a child process that makes another child process and i want to use pipes between them.

and also i want to know how to synchronize the execution among them

any help??

Last edited by alhashme; 12-07-2013 at 10:39 AM.
 
Old 12-07-2013, 11:00 AM   #2
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
any help pleas...
 
Old 12-07-2013, 12:39 PM   #3
btmiller
Senior Member
 
Registered: May 2004
Location: In the DC 'burbs
Distribution: Arch, Scientific Linux, Debian, Ubuntu
Posts: 4,290

Rep: Reputation: 378Reputation: 378Reputation: 378Reputation: 378
What exactly do you need help with? Your question is extremely broad.

It's been awhile since I've done this, but if I remember correctly, you use pipe(2) before forking, then go ahead and fork, and afterwards close the reader end on the master and the writer end on the child (or vice versa if you need the child to write to the parent).

For synchronization, you can use any number of techniques such as semaphores or lock files.

Since you don't tell us what language you're using oe anything else, it's hard to say more. This also sounds suspiciously like it might be homework. Why don't you show us the code you've got and highlight the areas where you're having problems? Then we might be able to help more.
 
Old 12-07-2013, 02:01 PM   #4
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
hi..
i'm sorry that my question was not clear,

I want the parent process to generate array of random numbers and send it to the first child,
then the first chiled process reads the array from the pipe and prints the evens,
then the first chiled process forks another child (second child) and send to it the odd numbers
finally the second child will prints the odd numbers.


this is my code followed by the result i get:

Code:
#include<sys/wait.h>
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fstream>
#include<string.h>
#include<iostream>
#include<cstdlib>

using namespace std;
int main()
{
   int parent_id = getpid();
   int child_id;
   
      
   int n;
   cout<<"Enter number of randoms: ";
   cin>>n;

   char x[n];      // first array to hold the random numbers and send it to first child
   char ch[n];     // second array to the first child to receive the first array
   char ch2[n];    // third array to the second child to receive the array of odd numbers
   
   for(int i=0 ; i<n ; i++)
    {
      x[i] = static_cast<char>((rand()%30)+1);
      cout<<static_cast<int>(x[i])<<"\t";
    }
    cout<<"\n";
   
   int p1[2];   //
   pipe(p1);   // first pipe
   int r =fork();  
   
   if (r == 0)
   {
      waitpid(parent_id,NULL,0);
      
      id1 = getpid();
      
      cout<<"implementation of child 1\n";
      
      close(p1[1]);
      read(p1[0],ch,sizeof(x));  // read the array of random numbers
      
      int x = sizeof(x);
      
      for(int i=0 ; i<x ; i++)
       {
      	 int m = static_cast<int>(ch[i]);
      	 
         if((m % 2) == 0)
          {
           cout<<m<<"\t";
           
           //delet the even number after printing it
           for(int j=i ; j<x-1 ; j++)
           ch[j] = ch[j+1];
           
           x--;
          }
       }
      
      cout<<"\n";
             
      int p2[2];  //
      pipe(p2);  // second pipe inside the first child
      int r2 = fork();
       
       if(r2 == 0)
          { 
            waitpid(child_id,NULL,0);
            
            cout<<"implementation of child 2\n";
         
            close(p2[1]);
            read(p2[0],ch2,sizeof(ch));  // read the odd numbers
            
            for(int i=0 ; i<sizeof(ch2) ; i++)
              cout<<static_cast<int>(ch2[i]);<<"\t";
            
            cout<<"\n";
          }
        
       else
         {
           close(p2[0]);
           write(p2[1],ch,x+1);  // write the odd numbers
           exit(0);
         }

   }
   
   else
     {
       close(p1[0]);
       write(p1[1],x,strlen(x)+1);  // write the array of random numbers to first child
       exit(0);
     }
   
   
   return 0;
}
Quote:
ubuntu@ubuntu-desktop:~$ c++ as3.cpp
ubuntu@ubuntu-desktop:~$ ./a.out
Enter number of randoms: 4
14 17 28 26
implementation of child 1
ubuntu@ubuntu-desktop:~$ 14 28
implementation of child 2
17 26 26 -65

Last edited by alhashme; 12-07-2013 at 02:06 PM.
 
Old 12-08-2013, 06:34 AM   #5
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
this is my code above

any help..
 
Old 12-08-2013, 06:54 AM   #6
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
I remember doing something like that long ago. With mplayer to feed ffmpeg a video stream to add audio to the tv card video while forcing a known framerate from an unpredictable input framerate from the card. But there's modern obstacles with multiple cores and that script no longer works for me. And various other scripts running in dash and not bash even when a users default shell is bash and not dash in debian. One workaround is starting the script with bash, and not sh and not ./. I'm assuming that you'll be using something like named pipes. Just be aware that your script(s) could be right, but the execution environment is stepping on your toes.
 
Old 12-08-2013, 09:25 AM   #7
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Shadow_7 View Post
I remember doing something like that long ago. With mplayer to feed ffmpeg a video stream to add audio to the tv card video while forcing a known framerate from an unpredictable input framerate from the card. But there's modern obstacles with multiple cores and that script no longer works for me. And various other scripts running in dash and not bash even when a users default shell is bash and not dash in debian. One workaround is starting the script with bash, and not sh and not ./. I'm assuming that you'll be using something like named pipes. Just be aware that your script(s) could be right, but the execution environment is stepping on your toes.
i know that i should use the pipe but how to do that between three processes ???

and also how to control the execution among them

anyone knows?
 
Old 12-08-2013, 09:36 AM   #8
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
The big warning with pipes are that they are NOT synchronized, and you CAN'T use it for bi-directional communications - you will deadlock.

A pipe is intended for one way communication for independent processes. No "control" is necessary, as a process writing to a pipe will block until there is room for the data, a process reading from a pipe will block until there is data to read.

A pipe cannot be used by three processes. Process A cannot be talking to process B and C over the same pipe. Process A can send data to process B. Process B can send data to process C. If B is waiting for data from A, then it cannot be sending data to C.

You cannot have process A sending data to B, and B sending data to process A - this is the source of deadlocks as both processes will end up waiting for data... and neither one can send. This only sort of works with very short messages (you still need two pipes though), but only until one process or the other
goes into a wait for data...

If you DO want shared communication, then use a socket - that IS designed for two-way communication. It can even be used for multi-way communication.
 
Old 12-08-2013, 03:33 PM   #9
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
With named pipes you can have multiple pipes with different names. Although I've never used more than one. And I really don't script or code as much as I could. I seem to recall the term hook from programming land, although probably a dated term. Most things these days tend to favor network communications. Which is annoying when a local noise making application (synth) doesn't want to work because the network isn't fully configured. It makes noise, it has nothing to do with a network. But alas, the audio application doesn't work if you don't have your network fully setup. To include setting up an IP for your hostname in /etc/hosts.
 
Old 12-08-2013, 06:39 PM   #10
Spect73
Member
 
Registered: Aug 2013
Distribution: Slackware 14.1
Posts: 128

Rep: Reputation: Disabled
"Advanced Programming in the UNIX Environment, 2nd Edition" by Stephen A. Rago is my bible. If you can, I'd recommend you obtain a copy of it. It covers pipes, sockets, threads, IPC etc.
 
Old 12-08-2013, 07:40 PM   #11
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by Shadow_7 View Post
With named pipes you can have multiple pipes with different names. Although I've never used more than one. And I really don't script or code as much as I could. I seem to recall the term hook from programming land, although probably a dated term. Most things these days tend to favor network communications. Which is annoying when a local noise making application (synth) doesn't want to work because the network isn't fully configured. It makes noise, it has nothing to do with a network. But alas, the audio application doesn't work if you don't have your network fully setup. To include setting up an IP for your hostname in /etc/hosts.
Yes, but you still are subject to deadlocks (been there done that).

And you don't need a network to use domain sockets (socketpair). You only need to use IP numbers if you want to communicate with a different host. This is how X works normally. The X server has a named socket that all the clients can use to make connection requests over, when the connections are accepted, the server gets a new socket (bidirectional) for the purpose of communicating with the client.
 
Old 12-09-2013, 02:10 AM   #12
alhashme
LQ Newbie
 
Registered: Oct 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
did anybody read the code ??
 
Old 12-09-2013, 06:23 AM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by alhashme View Post
did anybody read the code ??
Yes, and as btmiller said, you're question is very broad. I've written several blog entries about architecture which I probably should revisit to make sure they're clearly written; they are lengthy because these topics are lengthy.

My preferred architecture is that there is a central daemon which creates all the children, then monitors the children and restarts them or reports system error. Meanwhile I use a lot of pipes to communicate between the various processes which have been created. The purposes of most of my architectures are to move data, for example from sensor devices to a user interface; such as a graphing application, or even just to disk if it's acting as a data recorder. The point there is a lot of these processes communicate not only with each other, but with device layers; such as USB serial, so as a result select() is very useful to determine if there is new data on one or more file handles which a process has open.

Entry about creating a daemon: Creating a daemon, includes some pipe examples.

Entry about using Pipes: Using PIPES for IPC

Entry about using select(): Select Overview

Entry about monitoring defunct processes: Monitoring to avoid zombie processes

The select() one was probably my first entry and is lacking in good examples.

The daemon one is likely the closest to the concepts you're asking about; which is to create multiple processes which communicate via pipes.
 
Old 12-09-2013, 06:36 AM   #14
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
Quote:
Originally Posted by alhashme View Post
did anybody read the code ??
Of course not. Code is scary. And it's an obvious homework assignment.

c++ to compile instead of g++? functionally the same, as /usr/bin/c++ links to /etc/alternatives/c++ which links to /usr/bin/g++. And the white space abuse makes it more difficult to read by humans.

$ man fork
$ man pipe

Note the "unidirectional" as in one way of pipe. With pipefd[0] being the READ end and pipefd[1] being the WRITE end.
 
Old 12-09-2013, 06:44 AM   #15
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
Maybe this tutorial is helpfull: http://beej.us/guide/bgipc/
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:49 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration