PDA

View Full Version : process programming



St0rM-MaN
09-14-2007, 05:41 PM
Hi all this is the first lesson in Linux programming :
it might be BAD or not but this is what i got for now;
author : St0rM-MaN
license : Rippers License / GPL
site : http://programming-fr34ks.net
title : Process programming under Linux


Let's rock :

first of all what is a process ?

1-it's the system way to define running programs and manage it
2-you can imagine a process as a something that executes a given piece of code
3-you can imagine it as an instance or a programs runs sequentially .
didn't get any thing right?
remember the definition of a program ?

several instruction executes to give a meaningful something right
well , the process is the actual execution of this instruction (quoted from wiki)
remember that every process in Unix is a child of another one and has the same code as it (fork()-ed) ,
or child that has different code (exec*()-ed)
so a process is the shell of program ;

process can executes several program ,
processes can executes one program or more at the same time;

Re-Entrancy :
means that 2 or more processes try to execute a piece of code at the same time or a single process try to execute a function several times (simultaneously) .

data section in each process is separate from the other

that means if we have 2 process
p1 , p2
each process runs program ttt
both of this process has it's own distinct copy of ttt's variables

compile this program and run it don't worry your self about understanding it now;

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>


int main()
{
pid_t cc;

int i=6;

cc = fork(); /*duplicate the running process */

switch (cc)
{
case 0:
i=17;
printf("CHILD\n");
printf("&#37;d\n",i);
_exit(0); /* that's where the child ends */
break;
default:
printf("parent\n");
printf("%d\n",i);
break;
}
return 0;
}
you will notice that 17 printed once in child process , put in the parent one it prints 6

now it's time to say hi to fork(); system cal

SYNOPSIS
#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);
creates new process by duplicating the parent process (where the fork was called)

return value :
0 in the child process this is why we switched and checked for 0 in the previous code
in parent process it returns the pid of it's child
-1 on error and global variable errno is set to the right error number
causes the current process (which it was called) to separate into 2 process
parent , child ; all memory pages , file descriptors table , etc;

after forking both child and parent starts execution from where was fork(); called

hello world ?

#include<stdio.h>
#include<errno.h> /*errno global variable*/
#include<unistd.h> /*fork();*/
#include<sys/types.h> /*pid_t */

int main()
{
pid_t child_pid; /*to distinguish where are we , child or parent*/

child_pid = fork(); /*here come duplicate process and start execution of
*both of them from here*/
switch (child_pid) /*check the return value */
{
case -1:
perror("fork");
_exit(1);
break;
case 0:/*inside the child */
printf("Hy i am a child and my PID is %d\n",(int) getpid());
_exit(0); /*process is done so exit*/
break;
default : /*parent*/
printf("Hy i am the parent and i have a child and it's pid is %d\n",
(int)child_pid);
break;
}
return 0;
}
1- include headers
2-declare a variable to save return value form fork();
3- switch this variable
4- check for error
6-check for which process are we in (parent / child )
8-print messages

if you noticed that the pid of the child is the same as child-pid in parent
man fork right now;

there is one thing that we didn't mention yet ;
process death :
when the child is dead it's not actually dead (turned into a ZOMBIE (a living dead));
why is that ? and is it so important to know ? yes it Is
this zombie process is still hanging in our system
so how to get ride of it ?
first let your self know that :
1 - when a child dies it turns into zombie tell the parent know it's dead by waiting for it's exit status or by SIGNALS
2- when a parent is dead before it's child , child process is now orphan and has now father
so the INIT process inherit it . INIT has pid no 1 check it out :

ps -A | grep "init"
don't forget to acknowledge your child process death or it will turn into zombie and consume your system pids (remember fork bomb)
you can deal with it by

ps -A | grep "defunct" and it will show you zombie process

first wait(); system call:

SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);
system call used to check child's status change
quote form man pages:

A state change
is considered to be: the child terminated; the child was stopped by a signal; or the
child was resumed by a signal. In the case of a terminated child, performing a wait
allows the system to release the resources associated with the child; if a wait is not
performed, then terminated the child remains in a "zombie" state (see NOTES below).

on success returns the terminated child pid;
on error returns -11
but there is a little problem that when you call this system call it suspends the parent process and waits for child termination that will disallow us to continue in our parent process execution but we will get over this in another example using the beautiful signals
also mention that if the process is already turned into zombie wait returns immediately

also waitpid(); is a good system call and I will explain it in another example after this

pid_t waitpid(pid_t pid, int *status, int options);

modify our example now
in this example we sleep 5 seconds in the child process ; it suppose that parent process will executes it's statement but no it waits for child termination try and remove this call and watch your it your self;

#include<stdio.h>
#include<errno.h> /*errno global variable*/
#include<unistd.h> /*fork();*/
#include<sys/types.h> /*pid_t */
#include<sys/wait.h> /*wait()*/
int main()
{
pid_t child_pid; /*to : distinguish where are we , child or parent*/

int status;

child_pid = fork(); /*here come duplicate process and start execution of
*both of them from here*/
switch (child_pid) /*check the return value */
{
case -1:
perror("fork");
_exit(1);
break;
case 0:/*inside the child */
printf("Hy i am a child and my PID is %d\n",(int) getpid());
sleep(5);
_exit(0); /*process is done so exit*/
break;
default : /*parent*/

wait(&status);
printf("Hy i am the parent and i have a child and it's pid is %d\n",
(int)child_pid);
break;
}

return 0;
}

after 5 seconds child will exit and wait() system call store child termination number and executes it's statement
end of the story :D child was buried and didn't turned into zombie
but this is not a good usage of multi-process programming as you wait for another process to executes your process
know it's time to tell you the truth :( I am not your father :D
when a child dies it sends SIGCHLD signal to it's parent ; so we can set up a good signal handler to deal with it's death

void sig(int signo)
{
int stat;
signal(SIGCHLD , sig)
printf("CHILD WAS DEAD\n");
wait(&stat); /* clear off the zombie process*/
}
lt's start :D

#include<stdio.h>
#include<signal.h> /*signal();*/
#include<errno.h> /*errno global variable*/
#include<unistd.h> /*fork();*/
#include<sys/types.h> /*pid_t */
#include<sys/wait.h> /*wait()*/
/*signal handler
* called when SIGCHLD recevied*/
void sig_chld(int sig_no)
{
signal(SIGCHLD , sig_chld);
int stat;
printf("CHILD WAS DEAD\n");
wait(&stat);
}

int main()
{

signal(SIGCHLD , sig_chld); /* announce that whenever SIGCHLD recived
*call sig_chld function*/

pid_t child_pid; /*to destanguish where are we , child or parent*/

int i;

child_pid = fork(); /*here come duplicate process and start execution of
*both of them from here*/
switch (child_pid) /*check the return value */
{
case -1:
perror("fork");
_exit(1);
break;
case 0:/*inside the child */
printf("Hy i am a child and my PID is %d\n",(int) getpid());
sleep(5);
_exit(0); /*process is done so exit*/
break;
default : /*parent*/
printf("Hy i am the parent and i have a child and it's pid is %d\n",
(int)child_pid);
break;
}

printf("THIS IS THE PARENT PROCESS\n");
for(i=0; i < 10; i++)
{
printf("I AM A PARENT AND I AM ENJOYING MY EXECUTION WIL MY CHILD IS SLEEPING\n");
sleep(1); /* one second the executes the loop again*/
}

return 0;
}

we did nothing more than defining a signal handler and associate SIGCHLD with this handler

if (and it will be) there is mistakes or something wrong or anything i've done
PLEAS TELL ME !

zacs7
09-15-2007, 06:24 AM
Sorry what's the point of this thread?

The subtitle of this forum suggests it's for questions, "Questions specific to linux programming" not tutorials, nor for asking people to edit / proof read your tutorials.

St0rM-MaN
09-15-2007, 07:53 AM
oooh , sorry i didn't noticed
"Questions specific to linux programming"

any way i didn't mean any thing with it , just sharing nothing more nothing less