The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
.
google unix.com



High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
URGENT:::Can anybody help me in creating message queue appliction?? arunchaudhary19 High Level Programming 9 11-20-2007 07:15 AM
creating 10 process kpkant123 Shell Programming and Scripting 2 05-21-2007 05:28 PM
creating child process Confuse High Level Programming 12 05-27-2005 11:48 AM
Redirection or piping error message mariner Shell Programming and Scripting 2 05-10-2005 03:04 PM
How to know a new file is in process of creating? It has not been closed. linkjack High Level Programming 2 02-11-2003 01:55 PM

Reply
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 06-16-2009
p00ndawg p00ndawg is offline
Registered User
  
 

Join Date: Jun 2009
Posts: 8
Creating 3 process and piping a message

sorry im very new to this but i am supposed to create 3 processes A,B, and C and have a direct link from a to b, b to c, and c to a.

here is my code. It does work, however if you look at what I bolded as long as my final read is p[0] it seems to always work, regardless of the bolded section.

can anyone explain this?

Code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MSGSIZE    14 
 
char *message = "hello, world!"; 
 
 
main() { 
char inbuf[MSGSIZE];
int p[3];

pid_t pid;
pid_t pid1;
 
if (pipe(p) == -1){ 
perror("pipe call"); 
exit(1); 
 
}


pid = fork();
pid1 = fork();


if(pid == -1){

perror("Fork failed");
exit(1);

}

if(pid | pid1 == 0)//process A
{
    close(p[0]); 
    write(p[1], message, MSGSIZE);
    read(p[1], message, MSGSIZE);
    write(p[2], message, MSGSIZE);
    
}

/*else if(pid1 == 0){

    close(p[1]);
    //read(p[1], message, MSGSIZE);
    write(p[2], message, MSGSIZE);
    
}*/


else{
    //parent process C
    close(p[2]); 
    read(p[0], inbuf, MSGSIZE);
    printf("Pipelined message return:%s\n", inbuf);
    wait(NULL); 
}

exit(0);
}

Last edited by vino; 06-17-2009 at 12:52 AM..
  #2 (permalink)  
Old 06-22-2009
lagigliaivan lagigliaivan is offline
Registered User
  
 

Join Date: May 2008
Posts: 45
Hi

I don't understand very well this peace of code you wrote:

Code:
if(pid | pid1 == 0)//process A
This works as
Code:
 if ( pid | (pid1 == 0) )
and I don't understand really well what is the idea, could clarify it?


The code above is a OR operation and the if sentence will be performed according its result right?

---------- Post updated at 05:18 PM ---------- Previous update was at 05:16 PM ----------

I don't understand very well this piece of code you wrote:


if(pid | pid1 == 0)//process A

This works as

if ( pid | (pid1 == 0) )

and I don't understand really well it this is the idea, could you clarify it?

The code above is a OR operation and the if sentence will be performed according its result, right?
  #3 (permalink)  
Old 06-28-2009
p00ndawg p00ndawg is offline
Registered User
  
 

Join Date: Jun 2009
Posts: 8
Quote:
Originally Posted by lagigliaivan View Post
I don't understand very well this peace of code you wrote:

Code:
if(pid | pid1 == 0)//process A
This works as
Code:
 if ( pid | (pid1 == 0) )
and I don't understand really well what is the idea, could clarify it?


The code above is a OR operation and the if sentence will be performed according its result right?

---------- Post updated at 05:18 PM ---------- Previous update was at 05:16 PM ----------

I don't understand very well this piece of code you wrote:


if(pid | pid1 == 0)//process A

This works as

if ( pid | (pid1 == 0) )

and I don't understand really well it this is the idea, could you clarify it?

The code above is a OR operation and the if sentence will be performed according its result, right?
yea I did that because i created two forks, but i wanted both to enter the switch statement.
  #4 (permalink)  
Old 06-30-2009
tetsujin tetsujin is offline
Registered User
  
 

Join Date: Apr 2009
Posts: 4
Quote:
Originally Posted by p00ndawg View Post
Code:
pid = fork();
pid1 = fork();
OK, first off, you've got a total of four processes here, not three... (Is that what you wanted? For the process I call A to spawn off three children? Or did you want three processes total?)

Process A (original process): pid = B, pid1 = C
Process B (first child of A): pid = 0, pid1 = D
Process C (second child of A): pid = B, pid1 = 0
Process D (child of B): pid = 0, pid1 = 0

Quote:
Code:
if(pid | pid1 == 0)//process A
This if statement will actually run for three of the four processes: A, C, and D:
Process A: (pid | pid1 == 0) = (B | C == 0) = (B | 0) = true
Process B: (pid | pid1 == 0) = (0 | D == 0) = (0 | 0) = false
Process C: (pid | pid1 == 0) = (B | 0 == 0) = (B | true) = true
Process D: (pid | pid1 == 0) = (0 | 0 == 0) = (0 | true) = true
(where true is some nonzero value...)

Quote:
Code:
{
    close(p[0]); 
    write(p[1], message, MSGSIZE);
    read(p[1], message, MSGSIZE);
    write(p[2], message, MSGSIZE);
}
p[2] is uninitialized. pipe() only creates two file descriptors: p[0], the read end of the pipe, and p[1], the write end of the pipe.

Also, from the problem description it sounded like you wanted each of the three communicating processes to have the ability to write messages to and receive messages from each of the other two communicating processes. This suggests you need to create at least three pipes (three invocations of pipe() in the parent process). I say "at least three pipes" because if these processes are running concurrently, allowing two processes to write to the same file descriptor could have unpredictable results. (Using write() to write a single, whole message will probably be safe - but if the message were large it's possible the write would block waiting for the reader to read some data out - in which case I think it's possible the other process's write() could wind up getting in before the first write() finishes its message. (Not sure, though. write() is a system call so the kernel may synchronize it...)

Remember that pipe() creates two file descriptors but just one pipe. A pipe with an input end and an output end. A file descriptor you get from pipe() is either read-only or write-only - you can never read and write from the same file descriptor, when the file descriptor was obtained with pipe().
  #5 (permalink)  
Old 06-30-2009
p00ndawg p00ndawg is offline
Registered User
  
 

Join Date: Jun 2009
Posts: 8
Quote:
Originally Posted by tetsujin View Post
OK, first off, you've got a total of four processes here, not three... (Is that what you wanted? For the process I call A to spawn off three children? Or did you want three processes total?)

Process A (original process): pid = B, pid1 = C
Process B (first child of A): pid = 0, pid1 = D
Process C (second child of A): pid = B, pid1 = 0
Process D (child of B): pid = 0, pid1 = 0



This if statement will actually run for three of the four processes: A, C, and D:
Process A: (pid | pid1 == 0) = (B | C == 0) = (B | 0) = true
Process B: (pid | pid1 == 0) = (0 | D == 0) = (0 | 0) = false
Process C: (pid | pid1 == 0) = (B | 0 == 0) = (B | true) = true
Process D: (pid | pid1 == 0) = (0 | 0 == 0) = (0 | true) = true
(where true is some nonzero value...)



p[2] is uninitialized. pipe() only creates two file descriptors: p[0], the read end of the pipe, and p[1], the write end of the pipe.

Also, from the problem description it sounded like you wanted each of the three communicating processes to have the ability to write messages to and receive messages from each of the other two communicating processes. This suggests you need to create at least three pipes (three invocations of pipe() in the parent process). I say "at least three pipes" because if these processes are running concurrently, allowing two processes to write to the same file descriptor could have unpredictable results. (Using write() to write a single, whole message will probably be safe - but if the message were large it's possible the write would block waiting for the reader to read some data out - in which case I think it's possible the other process's write() could wind up getting in before the first write() finishes its message. (Not sure, though. write() is a system call so the kernel may synchronize it...)

Remember that pipe() creates two file descriptors but just one pipe. A pipe with an input end and an output end. A file descriptor you get from pipe() is either read-only or write-only - you can never read and write from the same file descriptor, when the file descriptor was obtained with pipe().
yes I actually wanted processes A, B, and C communicating with each other, but I only wanted to pipe a message from a->b->c. I didnt realize I had created 4 processes.
Is there anyway to just create 3 processes? how about a way to just get variable pipes communicating with each other?

Thanks for the awesome breakdown.

Last edited by p00ndawg; 06-30-2009 at 09:29 PM..
  #6 (permalink)  
Old 06-30-2009
tetsujin tetsujin is offline
Registered User
  
 

Join Date: Apr 2009
Posts: 4
Quote:
Originally Posted by p00ndawg View Post
yes I actually wanted processes A, B, and C communicating with each other, but I only wanted to pipe a message from a->b->c. I didnt realize I had created 4 processes.
Is there anyway to just create 3 processes? how about a way to just get variable pipes communicating with each other?
Sure. The reason you wound up with a total of four processes is because each call to fork() returns twice: once in the original process and once in the new one. So after you make the first call to fork(), there are two processes - both of which go on to call the second fork().

To create a total of three processes, make sure you only fork twice. You can do this by checking the return value of fork() to make sure you're in the process which should fork.

Code:
pid_b = fork();
if (pid_b == 0)
{
    /* fork() returned 0, so this is the new process, which I call process B. */
    pid_c = fork();
    if (pid_c == 0)
    {
        /* This is process C... */
    }
}
Now, if your communication channels only need to be such that A can send messages to B, and B can send messages to C, you wind up with something like this:

Code:
pipe(channel_ab);
 pid_b = fork();
if (pid_b > 0)
{
    /* Process A...  Send messages to B using channel_ab[1] */
    close(channel_ab[0]);
    write(channel_ab[1], msg, size);
} else if (pid_b == 0) {
    /* Process B */
    close(channel_ab[1]);

    pipe(channel_bc);
    pid_c = fork();
    if (pid_c > 0)
    {
        /* Still process B.  Receive messages from A using channel_ab[0], send messages to C using channel_bc[1]. */
        close(channel_bc[0]);
        msg_size = read(channel_ab[0], buffer, size);
        write(channel_bc[1], msg, size);
    } else if (pid_c == 0) {
        /* Process C.  Receive messages from B using channel_bc[0]. */
        msg_size = read(channel_bc[0], buffer, size);
    }
}
'Course there's various error checking and stuff you'd want to do in there that's not shown above - but that's the basic idea.
  #7 (permalink)  
Old 07-01-2009
p00ndawg p00ndawg is offline
Registered User
  
 

Join Date: Jun 2009
Posts: 8
Quote:
Originally Posted by tetsujin View Post
Sure. The reason you wound up with a total of four processes is because each call to fork() returns twice: once in the original process and once in the new one. So after you make the first call to fork(), there are two processes - both of which go on to call the second fork().

To create a total of three processes, make sure you only fork twice. You can do this by checking the return value of fork() to make sure you're in the process which should fork.

Code:
pid_b = fork();
if (pid_b == 0)
{
    /* fork() returned 0, so this is the new process, which I call process B. */
    pid_c = fork();
    if (pid_c == 0)
    {
        /* This is process C... */
    }
}
Now, if your communication channels only need to be such that A can send messages to B, and B can send messages to C, you wind up with something like this:

Code:
pipe(channel_ab);
 pid_b = fork();
if (pid_b > 0)
{
    /* Process A...  Send messages to B using channel_ab[1] */
    close(channel_ab[0]);
    write(channel_ab[1], msg, size);
} else if (pid_b == 0) {
    /* Process B */
    close(channel_ab[1]);

    pipe(channel_bc);
    pid_c = fork();
    if (pid_c > 0)
    {
        /* Still process B.  Receive messages from A using channel_ab[0], send messages to C using channel_bc[1]. */
        close(channel_bc[0]);
        msg_size = read(channel_ab[0], buffer, size);
        write(channel_bc[1], msg, size);
    } else if (pid_c == 0) {
        /* Process C.  Receive messages from B using channel_bc[0]. */
        msg_size = read(channel_bc[0], buffer, size);
    }
}
'Course there's various error checking and stuff you'd want to do in there that's not shown above - but that's the basic idea.
oh ok thanks alot, I think i understand now . I have a project coming up where ill need to use some pipes and I this really fills in some of my blanks.

thanks again.
Sponsored Links
Reply

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 05:19 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0