Fedora Linux Support Community & Resources Center
  #1  
Old 30th March 2009, 12:44 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
C program...processes.

ok...i wrote a program that takes user input within 5 secs 3 times ... the user should enter a number before the timer expires...

here is the code

Code:
/* This program checks if the user has "5" as input before the countdown is over or not*/

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>

int main()
{
    int x,i=0,pid,pid2;
    system("clear");
    for(x=0;x<3;x++)
    {
        pid=-1;pid2=-1;
        if((pid=fork()) == 0)   //child process- the countdown timer
        {
            pid=getpid();
            for(i=5;i>0;i--)    //start a 5 sec countdown
            {                   
                printf("X=%d\tenter number(ppid=%d,pid=%d)",x,getppid(),getpid());
                printf("\t\t\t\t\t\t\t%d\a\n",i);
                sleep(1);                                                                     
            }
            exit(666+x);      //exit when 5 secs are over
        }

        else      //parent process
        {       
           if((pid2=fork()) == 0)   //create a seperate child process for input
           { 
                pid2=getpid();
                printf("\n\nscanf pid2=%d\n\n",pid2);
                scanf("%d",&i);
                kill(pid,SIGKILL);     //when input is recieved kill the timer process
                 if(i==5)             //check the user input 
                {
                   printf("\nYES i=5(pid=%d) for x=%d\n\n",getpid(),x);                
                }
                else
                {
                    printf("\nNO i!=5(pid=%d) for x=%d\n\n",getpid(),x);                
                }                 
                exit(777+i);
           }     
           wait();      //wait for child process...timer process.         
           sleep(3);     //take a deep breath
           printf("\n\npid2=%d(i must execute only after wait() is over)\n\n",pid2);                                       
           if((kill(pid2,SIGKILL))==0)  //after the timer child process finishes ,if input process is still running...kill it
           {
               printf("\nNO i!=5(pid=%d) for x=%d\n\n",getpid(),x);//default msg
           }   
        }
    }
    printf("THE END(pid=%d\n",getpid());       //this should be executed when all other child processes are over.
    return 0;    
}
but i get a lot of unexpected behaviour...

this output is one example

Code:
#i wont be entering any input whatsoever...
X=0	enter number(ppid=24800,pid=24802)							5


scanf pid2=24803

X=0	enter number(ppid=24800,pid=24802)							4
X=0	enter number(ppid=24800,pid=24802)							3
X=0	enter number(ppid=24800,pid=24802)							2
X=0	enter number(ppid=24800,pid=24802)							1


pid2=24803(i must execute only after wait() is over)


NO i!=5(pid=24800) for x=0 #its ok till here...it waited till timer exited then executed the rest,killing scanf process.

X=1	enter number(ppid=24800,pid=24812)	#new timer process						5


scanf pid2=24813    #new child scanf process

X=1	enter number(ppid=24800,pid=24812)							4
X=1	enter number(ppid=24800,pid=24812)							3


pid2=24813(i must execute only after wait() is over) #why didnt it wait till timer process exited?


NO i!=5(pid=24800) for x=1 #this killed my scanf before the timer expired.

X=1	enter number(ppid=24800,pid=24812)							2
X=2	enter number(ppid=24800,pid=24817)							5


scanf pid2=24818   # x=2 has started before x=1 even finished

X=1	enter number(ppid=24800,pid=24812)							1   
#the sleep(3) statement never executed again
X=2	enter number(ppid=24800,pid=24817)							4
X=2	enter number(ppid=24800,pid=24817)							3
X=2	enter number(ppid=24800,pid=24817)							2


pid2=24818(i must execute only after wait() is over)


NO i!=5(pid=24800) for x=2

THE END(pid=24800    #the parent exits , leaving the timer process an orphan
[c_d@localhost C scratchpad]$ X=2	enter number(ppid=1,pid=24817)							1
the unexpected behaviour is highlighed with red...and commentaries are written by side of output in blue...

please comment.
__________________
c_d -- superfluously plenteous yet indolently otiose

Last edited by creeping death; 30th March 2009 at 01:38 PM.
Reply With Quote
  #2  
Old 30th March 2009, 02:19 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
well,

i just changed from wait to waitpid() and there has been a lot of improvement.

Code:
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>

int main()
{
    int x,i=0,pid,pid2,status,r;
    system("clear");
    for(x=0;x<3;x++)
    {
        pid=-1;pid2=-1;
        if((pid=fork()) == 0)   //child process- the countdown timer
        {
            pid=getpid();
            for(i=5;i>0;i--)    //start a 5 sec countdown
            {                   
                printf("X=%d\tenter number(ppid=%d,pid=%d)",x,getppid(),getpid());
                printf("\t\t\t\t\t\t\t%d\a\n",i);
                sleep(1);                                                                     
            }
            exit(111+x);      //exit when 5 secs are over
        }

        else      //parent process
        {       
           if((pid2=fork()) == 0)   //create a seperate child process for input
           { 
                pid2=getpid();
                //printf("\n\nscanf pid2=%d\n\n",pid2);
                scanf("%d",&i);
                kill(pid,SIGKILL);     //when input is recieved kill the timer process
                 if(i==5)             //check the user input 
                {
                   printf("\nYES i=5(pid=%d) for x=%d\n\n",getpid(),x);                
                }
                else
                {
                    printf("\nNO i!=5(pid=%d) for x=%d\n\n",getpid(),x);                
                }                 
                exit(0);
           }     
        
           r=waitpid(pid,&status); //wait for child process...timer process.         
           
           sleep(3);     //take a deep breath
           printf("\n\npid=%d,pid2=%d(wait status=%d,r=%d)\n\n",pid,pid2,status,r);                                       
           if((kill(pid2,SIGKILL))==0)  //after the timer child process finishes ,if input process is still running...kill it
           {
               printf("\nNO i!=5(pid=%d) for x=%d\n\n",getpid(),x);//since the user did not enter anything within time.display this
           }   
        }
    }
    printf("THE END(pid=%d\n",getpid());       //this should be executed when all other child processes are over.
    return 0;    
}
output:
Code:
X=0	enter number(ppid=7095,pid=7097)							5
X=0	enter number(ppid=7095,pid=7097)							4
X=0	enter number(ppid=7095,pid=7097)							3
X=0	enter number(ppid=7095,pid=7097)							2
X=0	enter number(ppid=7095,pid=7097)							1


pid=7097,pid2=7098(wait status=28416,r=7097)


NO i!=5(pid=7095) for x=0

X=1	enter number(ppid=7095,pid=7115)							5
X=1	enter number(ppid=7095,pid=7115)							4
X=1	enter number(ppid=7095,pid=7115)							3
X=1	enter number(ppid=7095,pid=7115)							2
X=1	enter number(ppid=7095,pid=7115)							1


pid=7115,pid2=7116(wait status=28672,r=7115)


NO i!=5(pid=7095) for x=1

X=2	enter number(ppid=7095,pid=7141)							5
X=2	enter number(ppid=7095,pid=7141)							4
X=2	enter number(ppid=7095,pid=7141)							3
X=2	enter number(ppid=7095,pid=7141)							2


pid=7141,pid2=7142(wait status=28672,r=0) #why is r=0 when pid=7141,in this case?


NO i!=5(pid=7095) for x=2

THE END(pid=7095
[c_d@localhost C scratchpad]$ X=2	enter number(ppid=1,pid=7141)							1 #orphaned yet again

[c_d@localhost C scratchpad]$
any ideas why the third time why return value of waitpid() was 0?
__________________
c_d -- superfluously plenteous yet indolently otiose

Last edited by creeping death; 30th March 2009 at 02:24 PM.
Reply With Quote
  #3  
Old 30th March 2009, 02:37 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
SUCCESS!

forgot to include <sys/wait.h>
__________________
c_d -- superfluously plenteous yet indolently otiose
Reply With Quote
  #4  
Old 31st March 2009, 10:45 AM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
final code

Code:
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include <sys/wait.h>
#define CL system
#define C "clear" 

int main()
{
    int x,i=0,pid,pid2,status;
    FILE *temp,*rf;         //temp will contain the marks,rf will contain if user gave an input or not
    temp=fopen("temp","w");
    fputc(0,temp);          //set marks to 0
    fputc(0,temp);
    fclose(temp);
    CL(C);                  //CL(C)=clear screen(see #define)
    for(x=0;x<3;x++)
    {
        CL(C);
        pid=-1;pid2=-1;
        if((pid=fork()) == 0)   //child process- the countdown timer
        {
            for(i=5;i>0;i--)    //start a 5 sec countdown
            {                   
                CL(C);
                printf("X=%d\tenter a number(ppid=%d,pid=%d)",x,getppid(),getpid());
                printf("\t\t\t\t\t\t\t%d\a\n",i);
                sleep(1);                                                                                     
            }
            exit(0);      //exit when 5 secs are over
        }
        else      //parent process
        {       
           if((pid2=fork()) == 0)   //create a seperate child process for input
           { 
                int noattempts,nocorrect,rval;
                rf=fopen("rval","w");   //set value in rval file to -1
                fclose(rf);               
                rval=scanf("%d",&i);
                rf=fopen("rval","w");   
                fputc(rval,rf);        //if scanf worked correctly then value in rval file will be 1
                fclose(rf);
                kill(pid,SIGKILL);     //when input is recieved kill the timer process
                temp=fopen("temp","r");
                noattempts=fgetc(temp);
                nocorrect=fgetc(temp);
                fclose(temp);
                
                if(i==5)               //check the user input 
                {
                   printf("\nYES i=5(pid=%d) for x=%d\n\n",getpid(),x);
                   noattempts++;
                   nocorrect++;                                   
                }
                else
                {
                    printf("\nNO i!=5(pid=%d) for x=%d\n\n",getpid(),x);                
                    noattempts++;
                }
                temp=fopen("temp","w");
                fputc(noattempts,temp);  //update marks
                fputc(nocorrect,temp);
                fclose(temp);                 
                exit(0);        //exit the scanf process.no need to kill this if user entered input appropriately
           }                
           waitpid(pid,&status,0); //wait for child process...timer process.                                 
           rf=fopen("rval","r");
           if(fgetc(rf)!=1)   //check if user entered input appropriately
           {
                printf("\nAppropriate input not specified\n");
                kill(pid2,SIGKILL);   
           }
           fclose(rf);           
        }        
        printf("\n\nNext question...");
        fflush(stdout);
        sleep(3);           //take a deep breath
    }
    CL(C);
    temp=fopen("temp","r");
    printf("THE END(pid=%d)\nNo of Correct=%d\nNo of Attempts=%d\n",getpid(),fgetc(temp),fgetc(temp)); //this should be executed when all other child processes are over.
    fclose(temp);
    remove("temp");      //cleanup
    remove("rval");      
    return 0;    
}
it works as i want it to , but here i m using files, to "pass" values from one process to another.

i m sure there are much more efficient ways...what other alternative do i have?
__________________
c_d -- superfluously plenteous yet indolently otiose
Reply With Quote
  #5  
Old 1st April 2009, 04:52 AM
aleph Offline
Banned (for/from) behaving just like everybody else!
 
Join Date: Jul 2007
Location: Nanjing, China
Posts: 1,332
Quote:
Originally Posted by creeping death View Post
it works as i want it to , but here i m using files, to "pass" values from one process to another.

i m sure there are much more efficient ways...what other alternative do i have?
Using a file to pass messages is not that bad an idea, but you don't have to use an actual on-disk file, just a pipe is enough.

There are a vast number of inter-process communication methods, such as signals, shared memory objects, and pipe/sockets.

For smaller programs you can also run the program in one process with several threads. I wrote something similar using POSIX threads. The program is too long (~100 lines) to post here, please look at the pastbin: http://aleph.pastebin.com/f60796f12

The comments in the code contains my opinions about the code.
__________________
Code:
from rlyeh import cthulhu
cthulhu.fhtagn()
Reply With Quote
  #6  
Old 1st April 2009, 07:14 AM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
thanks man...its really cool for you...

Quote:
just a pipe is enough.
i dont know what you are saying...

you can pass variables from one process to another using signals?

Quote:
...I wrote something similar using POSIX threads....
i m new to process/threads/signals stuff...so...is there a specific way to compile this?

because i get errors.
Code:
[c_d@localhost c scratchpad]$ gcc temp2.c
/tmp/ccoV9PqL.o: In function `main':
temp2.c:(.text+0x16d): undefined reference to `pthread_create'
temp2.c:(.text+0x190): undefined reference to `pthread_create'
temp2.c:(.text+0x1a3): undefined reference to `pthread_join'
temp2.c:(.text+0x1b6): undefined reference to `pthread_join'
collect2: ld returned 1 exit status

can you recommend a good book to guide me through all this...processes/threads/signals etc...good and small


have you thought of the stdin question on the other thread?
__________________
c_d -- superfluously plenteous yet indolently otiose

Last edited by creeping death; 1st April 2009 at 07:25 AM.
Reply With Quote
  #7  
Old 1st April 2009, 08:05 AM
aleph Offline
Banned (for/from) behaving just like everybody else!
 
Join Date: Jul 2007
Location: Nanjing, China
Posts: 1,332
1. (pipes) I mean, you don't have to use an on-disk file. Just connect the input and output of both processes. Look at the man page of pipe(2) and you'll see a fine example doing IPC via a pipe.

2. (signals) I talked about signals... of course singnals alone can't carry much information, but what if you don't have that much information to send... sometimes "hey, wake up!" is enough.

3. (threads) to compile the program, use the command
Code:
gcc -pthread whatever.c
There's also more information in the code comments.

4. (books) I'm teaching myself half-baked system programming. Don't take my words seriously. Get a real course.

5. (that stdin issue) no..

Hope that helps.
__________________
Code:
from rlyeh import cthulhu
cthulhu.fhtagn()
Reply With Quote
  #8  
Old 1st April 2009, 07:28 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
Quote:
Originally Posted by aleph View Post
1. (pipes) I mean, you don't have to use an on-disk file. Just connect the input and output of both processes. Look at the man page of pipe(2) and you'll see a fine example doing IPC via a pipe.
thanks for the tip. just saw that, it can only recognise byte stream...but what if i wished to send "222456.8973" (float) value from one process to another? the only way that i see is to convert the float to a sting , find the length ,and then write(with size_t count(3rd argument)=string length+1);
any other ideas?

Quote:
2. (signals) I talked about signals... of course singnals alone can't carry much information, but what if you don't have that much information to send... sometimes "hey, wake up!" is enough.
ok...thats what i did in my program...parent said to child "die kid!!".
Quote:
3. (threads) to compile the program, use the command
Code:
gcc -pthread whatever.c
There's also more information in the code comments.
my bad...btw i did not understand somethings...but i wont bother you until i read about thread myself first...hopefully i'll understand it fully when i read about it.

Quote:
4. (books) I'm teaching myself half-baked system programming. Don't take my words seriously. Get a real course.

5. (that stdin issue) no..

Hope that helps.
alright, but how is unix for programmer and users glass and ables?
__________________
c_d -- superfluously plenteous yet indolently otiose
Reply With Quote
  #9  
Old 2nd April 2009, 04:33 AM
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,871
Quote:
Originally Posted by creeping death View Post
thanks for the tip. just saw that, it can only recognise byte stream...but what if i wished to send "222456.8973" (float) value from one process to another? the only way that i see is to convert the float to a sting , find the length ,and then write(with size_t count(3rd argument)=string length+1);
any other ideas?
No - you misunderstand. It means the pipe is just a stream of bytes w/o and higher level structure. You can send floats or binary stuff just fine.
float myfloat = 3.14159265;
write(fd, &myfloat, sizeof(float));

or
struct foobar someAwefulStruct = { .... }
write(fd, &someAwefulStruct, sizeof(struct foobar));


The interprocess communication methods include pipes, unix local sockets(AF_UNIX or AF_LOCAL), shared memory, messages, semaphores, signals. Also you can create external devices (pseudo-ttys and fifos for example). It's a very rich set.

Interprocess communication is a complex topic unless the communication is rather trivial - like pipes.
Reply With Quote
  #10  
Old 2nd April 2009, 05:16 AM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
Quote:
Originally Posted by stevea View Post
No - you misunderstand. It means the pipe is just a stream of bytes w/o and higher level structure. You can send floats or binary stuff just fine.
float myfloat = 3.14159265;
write(fd, &myfloat, sizeof(float));

or
struct foobar someAwefulStruct = { .... }
write(fd, &someAwefulStruct, sizeof(struct foobar));


The interprocess communication methods include pipes, unix local sockets(AF_UNIX or AF_LOCAL), shared memory, messages, semaphores, signals. Also you can create external devices (pseudo-ttys and fifos for example). It's a very rich set.

Interprocess communication is a complex topic unless the communication is rather trivial - like pipes.
i had tried this before before posting.
Code:
#include<stdio.h>
#include<unistd.h>

int main()
{
    float f;   
    printf("normal way\n");
    scanf("%f",&f);
    printf("%f",f);
    fflush(stdout);
    printf("\nSystem call\n");
    read(STDIN_FILENO,&f,sizeof(float));
    perror("read");
    write(STDOUT_FILENO,&f,sizeof(float));
    perror("write");   
    return 0;
}
OP:
Code:
[c_d@localhost c scratchpad]$ gcc temp4.c
[c_d@localhost c scratchpad]$ ./a.out 
normal way
88888.8765
88888.875000
System call
88888.8765
read: Success
8888write: Success
[c_d@localhost c scratchpad]$ 8.8765
bash: 8.8765: command not found
[c_d@localhost c scratchpad]$
i had also seen sockets(2) and there were a list of domains given at socket.h...and i confused with what to use...thanks for mentioning AF_UNIX/AF_LOCAL.
__________________
c_d -- superfluously plenteous yet indolently otiose

Last edited by creeping death; 2nd April 2009 at 07:02 AM.
Reply With Quote
  #11  
Old 2nd April 2009, 11:12 AM
aleph Offline
Banned (for/from) behaving just like everybody else!
 
Join Date: Jul 2007
Location: Nanjing, China
Posts: 1,332
Are you TYPING a float point number to be read(2) from stdin? You are typing a series of chars which made up a textual representation of a float, not a float itself.
__________________
Code:
from rlyeh import cthulhu
cthulhu.fhtagn()
Reply With Quote
  #12  
Old 2nd April 2009, 12:20 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
ok

see this now...

the float variable is declared as well as initialised

Code:
[c_d@localhost c scratchpad]$ cat temp4.c
#include<stdio.h>
#include<unistd.h>

int main()
{
    float f=88888.8789;   
    fflush(stdout);
    write(STDOUT_FILENO,&f,sizeof(float));
    perror("\nwrite");   
    return 0;
}
    

    
[c_d@localhost c scratchpad]$ gcc temp4.c
[c_d@localhost c scratchpad]$ ./a.out
p��G
write: Success
[c_d@localhost c scratchpad]$
....well?
__________________
c_d -- superfluously plenteous yet indolently otiose
Reply With Quote
  #13  
Old 2nd April 2009, 04:27 PM
aleph Offline
Banned (for/from) behaving just like everybody else!
 
Join Date: Jul 2007
Location: Nanjing, China
Posts: 1,332
Quote:
Originally Posted by creeping death View Post

....well?
That's right. You just dumped a 32-bit float to the terminal, which is shown as gibberish (of course).

Just write another program that reads from stdin, decode the float and printf(2) it. Pipe the raw float to this program and you'll see how it's possible to do what you intended to do.
__________________
Code:
from rlyeh import cthulhu
cthulhu.fhtagn()
Reply With Quote
  #14  
Old 2nd April 2009, 04:56 PM
creeping death Offline
Registered User
 
Join Date: Feb 2008
Posts: 656
Quote:
Originally Posted by aleph View Post
That's right. You just dumped a 32-bit float to the terminal, which is shown as gibberish (of course).

Just write another program that reads from stdin, decode the float and printf(2) it. Pipe the raw float to this program and you'll see how it's possible to do what you intended to do.
of course? why do you say "of course"???? please explain...

so, write() just dumps bytes onto the terminal, printf() formats them appropriately first and then dumps them to terminal. is that right?
__________________
c_d -- superfluously plenteous yet indolently otiose
Reply With Quote
  #15  
Old 2nd April 2009, 04:59 PM
aleph Offline
Banned (for/from) behaving just like everybody else!
 
Join Date: Jul 2007
Location: Nanjing, China
Posts: 1,332
Quote:
Originally Posted by creeping death View Post
so, write() just dumps bytes onto the terminal, printf() formats them appropriately first and then dumps them to terminal. is that right?
Of course
__________________
Code:
from rlyeh import cthulhu
cthulhu.fhtagn()
Reply With Quote
Reply

Tags
programprocesses

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
max processes alin19 Using Fedora 6 12th November 2008 10:50 AM
System stability affected by program after program has been closed...? DennyCrane Using Fedora 0 29th June 2008 01:53 AM
Reading output from program, called inside another program clearer Programming & Packaging 2 20th February 2008 08:52 AM
See VNC Processes boxxa Using Fedora 7 22nd December 2006 10:53 PM
how to use shell program parameters in java program?? srujanabobba Using Fedora 1 10th August 2006 07:24 PM


Current GMT-time: 10:18 (Wednesday, 01-10-2014)

TopSubscribe to XML RSS for all Threads in all ForumsFedoraForumDotOrg Archive
logo

All trademarks, and forum posts in this site are property of their respective owner(s).
FedoraForum.org is privately owned and is not directly sponsored by the Fedora Project or Red Hat, Inc.

Privacy Policy | Term of Use | Posting Guidelines | Archive | Contact Us | Founding Members

Powered by vBulletin® Copyright ©2000 - 2012, vBulletin Solutions, Inc.

FedoraForum is Powered by RedHat