I am trying to do first child function, for example, printing out a string : hello!, and go back to parent process. Then, I forked anothrer n processes for the second child function, which will count the shared memory number. I suppose there only shows one "all done" in the end, but it shows two? thanks for your help!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#define NUM_LINES 5
char * shm;
void child_func(char *shm)
{
while (atoi(shm) != NUM_LINES)
{
// P(sem);
printf("now reading word:%d\n", atoi(shm) );
*shm+=1;
// V(sem);
}
exit(0);
}
void parent_func(pid_t pid)
{
int status;
pid_t pid_wait;
do
{
pid_wait = waitpid(pid, &status, WNOHANG);
}while (pid_wait != pid);
// printf("Process %d done\n", getppid());
}
int main(int argc, char const *argv[])
{
/* declarations */
pid_t pid[8];
int ret, shmid, status,corpse, i, ave, n;
char fn[20];
key_t key = 123;
char *string_back;
/* create share memory */
if ((shmid = shmget(key, SHMSIZE, IPC_CREAT|666)) <0)
{
perror("shmget");
exit(1);
}
/* attach shm */
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror("shmat");
exit(1);
}
/* init shm value */
*shm = '0';
/* input */
printf("please enter n:\n");
scanf("%d", &n);
/* section 1 */
pid[0] = fork();
if (pid[0] == 0) // child processes
{
printf("hello !\n");
}
else if (pid[0] >0)
{
parent_func(pid[0]);
}
/* section 2 */
for (i=0;i<n;i++)
{
pid[i] = fork();
if (pid[i] == 0) // child processes
{
child_func(shm);
}
else if (pid[i] >0)
{
parent_func(pid[i]);
}
}
printf("all done\n");
/* detach shm */
shmdt(shm);
/* destroy shm */
int retval = shmctl(shmid, IPC_RMID, NULL);
if (retval < 0) perror("remove shm");
return 0;
}
After adding exit(0) in first section, I only get one "all done" in the last, which is the answer I want.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#define NUM_LINES 5
char * shm;
void child_func(char *shm)
{
while (atoi(shm) != NUM_LINES)
{
// P(sem);
printf("now reading word:%d\n", atoi(shm) );
*shm+=1;
// V(sem);
}
exit(0);
}
void parent_func(pid_t pid)
{
int status;
pid_t pid_wait;
do
{
pid_wait = waitpid(pid, &status, WNOHANG);
}while (pid_wait != pid);
// printf("Process %d done\n", getppid());
}
int main(int argc, char const *argv[])
{
/* declarations */
pid_t pid[8];
int ret, shmid, status,corpse, i, ave, n;
char fn[20];
key_t key = 123;
char *string_back;
/* create share memory */
if ((shmid = shmget(key, SHMSIZE, IPC_CREAT|666)) <0)
{
perror("shmget");
exit(1);
}
/* attach shm */
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror("shmat");
exit(1);
}
/* init shm value */
*shm = '0';
/* input */
printf("please enter n:\n");
scanf("%d", &n);
/* section 1 */
pid[0] = fork();
if (pid[0] == 0) // child processes
{
printf("hello !\n");
/* problem solved here */
exit(0);
}
else if (pid[0] >0)
{
parent_func(pid[0]);
}
/* section 2 */
for (i=0;i<n;i++)
{
pid[i] = fork();
if (pid[i] == 0) // child processes
{
child_func(shm);
}
else if (pid[i] >0)
{
parent_func(pid[i]);
}
}
printf("all done\n");
/* detach shm */
shmdt(shm);
/* destroy shm */
int retval = shmctl(shmid, IPC_RMID, NULL);
if (retval < 0) perror("remove shm");
return 0;
}
Related
In fork child, if we modify a global variable, it will not get changed in the main program.
Is there a way to change a global variable in child fork?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int glob_var;
main (int ac, char **av)
{
int pid;
glob_var = 1;
if ((pid = fork()) == 0) {
/* child */
glob_var = 5;
}
else {
/* Error */
perror ("fork");
exit (1);
}
int status;
while (wait(&status) != pid) {
}
printf("%d\n",glob_var); // this will display 1 and not 5.
}
You can use shared memory (shm_open(), shm_unlink(), mmap(), etc.).
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static int *glob_var;
int main(void)
{
glob_var = mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*glob_var = 1;
if (fork() == 0) {
*glob_var = 5;
exit(EXIT_SUCCESS);
} else {
wait(NULL);
printf("%d\n", *glob_var);
munmap(glob_var, sizeof *glob_var);
}
return 0;
}
Changing a global variable is not possible because the new created process (child)is having it's own address space.
So it's better to use shmget(),shmat() from POSIX api
Or You can use pthread , since pthreadsare sharing the globaldata and the changes in global variable is reflected in parent.
Then read some Pthreads tutorial.
Here is an alternative solution.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
typedef struct
{
int id;
size_t size;
} shm_t;
shm_t *shm_new(size_t size)
{
shm_t *shm = calloc(1, sizeof *shm);
shm->size = size;
if ((shm->id = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) < 0)
{
perror("shmget");
free(shm);
return NULL;
}
return shm;
}
void shm_write(shm_t *shm, void *data)
{
void *shm_data;
if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
{
perror("write");
return;
}
memcpy(shm_data, data, shm->size);
shmdt(shm_data);
}
void shm_read(void *data, shm_t *shm)
{
void *shm_data;
if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
{
perror("read");
return;
}
memcpy(data, shm_data, shm->size);
shmdt(shm_data);
}
void shm_del(shm_t *shm)
{
shmctl(shm->id, IPC_RMID, 0);
free(shm);
}
int main()
{
int var = 1;
shm_t *shm = shm_new(sizeof var);
int pid;
if ((pid = fork()) == 0)
{ /* child */
var = 5;
shm_write(shm, &var);
printf("child: %d\n", var);
return 0;
}
/* Wait for child to return */
int status;
while (wait(&status) != pid);
/* */
shm_read(&var, shm);
/* Parent is updated by child */
printf("parent: %d\n", var);
shm_del(shm);
return 0;
}
Build with:
$ gcc shm.c -o shm && ./shm
The program should create 200000 integers and write 2000 to a shared memory. A forked process should read 2000 from shared memory and the parent should write the next 2000 to shared memory.
if i use the code below without sleep, the parent first creates all 200000 integers and then the child reads the same integers from shared memory.
With sleep everything looks good, but we have to use semaphore.
shm.c (parent):
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/wait.h>
#define N_DATA 200000
#define N_SHARED 2000
#define LOCK -1
#define UNLOCK 1
static struct sembuf semaphore;
char shmidArg[32];
char semidArg[32];
int *shmData;
int i, j;
int status;
char *strsignal(int sig);
pid_t pid;
static int shmid;
static int semid;
char *strsignal(int sig);
/** Semaphore Operation */
static int semaphore_operation (int op) {
semaphore.sem_num = 1;
semaphore.sem_op = op;
semaphore.sem_flg = IPC_NOWAIT;
if( semop (semid, &semaphore, 1) == -1) {
perror(" semop ");
exit (EXIT_FAILURE);
}
return 1;
}
int main(int argc, char **argv) {
/* Ein Shared-Memory-Segment einrichten */
shmid = shmget(IPC_PRIVATE, N_SHARED*sizeof(int), IPC_CREAT | SHM_R | SHM_W);
if (shmid == -1) {
perror("shmid");
exit(1);
}
printf("Shared-Memory-ID: %d\n",shmid);
/* Pointer zu Shared-Memory-Segment erhalten */
shmData = (int *)shmat(shmid,0, 0);
if (shmData == (int *)(-1)) {
perror("shmat");
exit(1);
}
/* Semaphore anlegen */
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | SHM_R | SHM_W);
if (semid < 0) {
perror("semid");
exit(1);
}
printf ("Semaphor-ID : %d\n", semid);
/* Semaphor mit 1 initialisieren */
if (semctl (semid, 0, SETVAL, (int) 1) == -1) {
perror("semctl");
}
snprintf(shmidArg,32, "%d", shmid);
snprintf(semidArg,32, "%d", semid);
/** erstellen des Kindprozesses */
pid = fork();
// Kindprozess
if (pid == 0) {
execlp("./shm_child",shmidArg,semidArg,NULL);
} else if (pid < 0) {
perror("Kindprozess konnte nicht erzeugt werden!");
return 1;
}
// Elternprozess
else {
/** ininitalisieren des Zufallsgenerator durch aktuellen Zeitstempel */
srand48(time(NULL));
for(i=0;i<N_DATA;i=i+N_SHARED) {
semaphore_operation(LOCK);
for (j=0; j<N_SHARED; j++) {
shmData[j] = lrand48();
//MSZ
//printf("SHM-->%d-->%d\n",i+1,shmData[i]);
}
// if(i == 0 || i == 2000) {
printf("Parent-->%d-->0-->%d\n",i,shmData[0]);
printf("Parent-->%d-->1999->%d\n",i,shmData[1999]);
// }
semaphore_operation(UNLOCK);
//sleep(1);
}
}
//MSZ
//sleep(2);
printf("PID: %d\n", pid);
if (waitpid(pid, &status, 0) == -1) {
perror("wait konnte nicht erzeugt werden!");
return 1;
}
if (WIFEXITED(status)) {
printf("Exitcode: %d\n", WEXITSTATUS(status));
semctl (semid, 0, IPC_RMID, 0);
shmctl (shmid, IPC_RMID, NULL);
//If process terminaded by a signal
} else if (WIFSIGNALED(status)) {
printf("Signal: %d %s\n", WTERMSIG(status), strsignal(WTERMSIG(status)));
semctl (semid, 0, IPC_RMID, 0);
shmctl (shmid, IPC_RMID, NULL);
}
}
shm_child.c (Child):
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define N_DATA 6000
#define N_SHARED 2000
#define LOCK -1
#define UNLOCK 1
int i,j;
int *shmData;
static int shmid;
static int semid;
static struct sembuf semaphore;
/** Semaphore Operation */
static int semaphore_operation (int op) {
semaphore.sem_num = 0;
semaphore.sem_op = op;
semaphore.sem_flg = SEM_UNDO;
if( semop (semid, &semaphore, 1) == -1) {
perror(" semop ");
exit (EXIT_FAILURE);
}
return 1;
}
int main(int argc, char **argv) {
shmid = atoi(argv[0]);
semid = atoi(argv[1]);
printf("\nshm_child shared memoryid:%d\n",shmid);
printf("shm_child Semaphoren-ID:%d\n",semid);
/* Pointer auf Shared-Memory erstellen */
shmData = (int *)shmat(shmid,0,0);
if (shmData == (int *)(-1)) {
perror("shmat");
exit(1);
}
for(i=0;i<N_DATA;i=i+N_SHARED) {
semaphore_operation(LOCK);
for(j=0;j<N_SHARED;j++) {
//printf("%d-->%d --> %d\n",i,j+1,shmData[j]);
}
// if(i == 0 || i == 2000) {
printf("child-->%d-->0-->%d\n",i,shmData[0]);
printf("child-->%d-->1999->%d\n",i,shmData[1999]);
// }
semaphore_operation(UNLOCK);
sleep(1);
}
return 0;
}
Please help us
Thank you guys
Edit: Thank you very much for your answers. I can't mark the right answer because i dont know what its right. But i dont want try anything more. 15 hours are enough
The writer process shall give reader a permission to read, and wait for the reading completion. After that the reader shall give writer a permission to proceed, and wait for writing completion.
This goal cannot be achieved with a single semaphore. You need two, along the lines of:
// parent aka writer
writer_barrier = semaphore(UNLOCKED);
reader_barrier = semaphore(LOCKED);
start_reader();
while(...) {
lock(writer_barrier);
write_data();
unlock(reader_barrier);
}
// child aka reader
while(....)
lock(reader_barrier);
read_data();
unlock(writer_barrier);
}
I have the following code which works fine with the sleep time. But I want to remove sleep and use semaphores to synchronize the threads ( so that the reader waits till data is available in shmptr.) How do I do that? What do I use:
sem_t mutex or
pthread_mutex_t mutex?
P.S : I tried using both above options separately (not shown in above code though) but didn't get desired result.Most of the times I was getting error in shmget in reader - "shmget in reader: No such file or directory".
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <semaphore.h>
#include <errno.h>
void *write(void *t)
{ char str[100] = "\0";
char str1[50];
key_t key;
char *shmptr;
int shmid;
if( (key = ftok("shmSemphore.c",'B')) == -1)
{
perror("ftok in writer");
pthread_exit(NULL);
}
if( (shmid = shmget(key, 1024, 0666 | IPC_CREAT)) == -1)
{
perror("shmget in writer");
pthread_exit(NULL);
}
shmptr = shmat(shmid,0,0);
if( (shmptr == (char *)(-1)))
{
perror("shmget in writer");
pthread_exit(NULL);
}
printf("ENter your text :- ");
//scanf("%s",str);
fgets(str,sizeof(str),stdin);
strcpy(shmptr,str);
sleep(2);
shmdt(shmptr);
if( shmctl(shmid, IPC_RMID, NULL) == -1 )
{
perror("shmctl");
exit(-1);
}
pthread_exit(NULL);
}
void *read(void *t)
{ sleep(2);
key_t key;
char *shmptr;
int shmid;
if( (key = ftok("shmSemphore.c",'B')) == -1)
{
perror("ftok in writer");
pthread_exit(NULL);
}
if( (shmid = shmget(key, 1024, 0)) == -1)
{
perror("shmget in reader");
pthread_exit(NULL);
}
shmptr = shmat(shmid,0,0);
if( (shmptr == (char *)-1))
{
perror("shmget in writer");
pthread_exit(NULL);
}
printf("your text:- %s \n",shmptr);
pthread_exit(NULL);
}
int main()
{
pthread_t reader,writer;
int rt;
long t = 0;
rt = pthread_create(&writer,NULL,write,(void *)t);
/*if(rt == -1)
{ perror("writer thread");
pthread_exit(NULL);
}*/
rt = pthread_create(&reader,NULL,read,(void *)t);
/*if(rt == -1)
{ perror("writer thread");
pthread_exit(NULL);
}*/
pthread_join(writer,NULL);
pthread_join(reader,NULL);
return 0;
}
I need to write a program that is creating a N amount of sub processes and every single one of them adds one to a shared memory variable. My idea is to use semaphores and shared memory, but the processes are not waiting for each other and the shared memory variable is also not working as I want it.
mydefs.h
#ifndef __MYDEFS__H__
#define __MYDEFS__H__
// Includes
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <memory.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/shm.h>
#endif // __MYDEFS__H__
main.c
#include "mydefs.h"
#define PROC_COUNT 3
#define INITAL_MARKER_VALUE 0
#define PID_LEN 32
char mypid[PID_LEN];
int main()
{
int i, shm_id;
sem_t mutex;
if(sem_init(&mutex,1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
printf("shmget error\n");
}
int *shmpointer = shmat(shm_id,0,0);
memset(mypid, 0, sizeof(mypid));
sprintf(mypid, "%06d", getpid());
for(i = 0; i < PROC_COUNT; i++)
{
if (fork() == 0)
{
while(sem_wait(&mutex)!=0);
execl("slaveproc", "slaveproc", mypid, (char *)0);
shmpointer += 1;
sem_post(&mutex);
perror("\n Can't exec slave program. Cause ");
exit(1);
}
}
sleep(1);
printf("%d\n", *shmpointer);
return 0;
}
slaveproc.c
#include "mydefs.h"
int marker; // Marker value
int main(int argc, char *argv[])
{
master_pid = atoi(argv[1]);
printf("\n --------------------------------------");
printf("\n I'm the slave proc!");
printf("\n My pid: %d", getpid());
printf("\n My master's pid: %d", master_pid);
printf("\n --------------------------------------");
for(;;) pause();
return 0;
}
The problem (or at least "a problem") is that mutex is not in shared memory: it's allocated on the stack. When you fork(), the new process will have a completely separate copy from the old process, so calling sem_wait(&mutex) on one process will not affect the other process's mutex at all.
You should put mutex in the shared memory:
int main()
{
int i, shm_id;
shm_id = shmget(IPC_PRIVATE, sizeof(sem_t) + 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
printf("shmget error\n");
}
int *shmpointer = shmat(shm_id,0,0);
sem_t *mutex = shmpointer;
shmpointer = (void*)shmpointer + sizeof(sem_t);
if(sem_init(mutex,1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
memset(mypid, 0, sizeof(mypid));
sprintf(mypid, "%06d", getpid());
for(i = 0; i < PROC_COUNT; i++)
{
if (fork() == 0)
{
while(sem_wait(mutex)!=0);
execl("slaveproc", "slaveproc", mypid, (char *)0);
shmpointer += 1;
sem_post(mutex);
perror("\n Can't exec slave program. Cause ");
exit(1);
}
}
sleep(1);
printf("%d\n", *shmpointer);
return 0;
}
You're also never writing to the memory in shmpointer (perhaps you meant (*shmpointer) += 1?), but I'll let you figure that out on your own.
I have a program with two processes that communicate with shared memory. On ctrl-c I want both processes to exit. I'm using a atomic_bool variable called stop to inform the processes to keep looping or exit when set to true. However when the atomic_bool variable stop is set to true the other process does not see the change. Meaning it still prints out 0 instead of 1, but the process that made the change shows 1. So why doesn't the second process see the change from false to true?
Control-c won't work for killing the process so use killall instead.
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
#include <stdatomic.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>
struct shared_map
{
atomic_bool stop;
};
struct shared_map *map;
int compare_and_swap_loop(atomic_bool target, int value)
{
/* Loop until we can succesfully update the the value. */
while(1)
{
/* Grab a snapshot of the value that need to be updated. */
bool snapshot = atomic_load(&target);
if(atomic_compare_exchange_weak(&target, &snapshot, value) == true)
{
/* We succesfully updated the value let's exit this loop and return. */
break;
}
}
printf("result: %d\n", atomic_load(&target));
return 0;
}
static void ctrlc_handler(int sig)
{
compare_and_swap_loop(&map->stop, true);
return;
}
void setup_signal_handler(void)
{
(void) signal(SIGINT, ctrlc_handler);
return;
}
static int create_shared(void **pointer, int size)
{
*pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if(*pointer == MAP_FAILED)
{
printf("mmap: %s\n", strerror(errno));
return -1;
}
return 0;
}
static void loop(void)
{
/* Set up signal handler. */
setup_signal_handler();
/* Check if we should stop or continue running. */
while(atomic_load(&map->stop) == false)
{
sleep(2);
printf("map->stop: %d\n", atomic_load(&map->stop));
}
return;
}
int main(void)
{
int rtrn;
pid_t pid;
rtrn = create_shared((void **)&map, sizeof(struct shared_map));
if(rtrn < 0)
{
printf("Can't create shared memory\n");
return -1;
}
atomic_init(&map->stop, false);
pid = fork();
if(pid == 0)
{
loop();
_exit(0);
}
else if(pid > 0)
{
int status;
waitpid(pid, &status, 0);
return 0;
}
else
{
printf("fork: %s\n", strerror(errno));
return -1;
}
return 0;
}
You're passing in a copy of your atomic variable to your compare_and_swap_loop function, which is not going to do you any good - you need to work on the same value that's shared between your processes.
You need to do it like this:
int compare_and_swap_loop(atomic_bool *target, int value)
{
/* Loop until we can succesfully update the the value. */
while(1)
{
/* Grab a snapshot of the value that need to be updated. */
bool snapshot = atomic_load(target);
if(atomic_compare_exchange_weak(target, &snapshot, value) == true)
{
/* We succesfully updated the value let's exit this loop and return. */
break;
}
}
printf("result: %d\n", atomic_load(target));
return 0;
}
the following code is written without the 'atomic_*' commands
but does show what is incorrect about your process.
Mostly, need to kill the child pid, not the parent pid
The following code displays the child pid, so it is easy to find
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
//#include <stdatomic.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>
struct shared_map
{
bool stop;
};
struct shared_map *map;
int compare_and_swap_loop( bool *target )
{
/* Loop until we can succesfully update the the value. */
while(1)
{
/* Grab a snapshot of the value that need to be updated. */
bool snapshot = *target;
if(snapshot)
{
/* We succesfully updated the value let's exit this loop and return. */
break;
}
}
return 0;
}
static void ctrlc_handler(int sig)
{
if( SIGINT==sig)
compare_and_swap_loop(&map->stop);
return;
}
void setup_signal_handler(void)
{
(void) signal(SIGINT, ctrlc_handler);
return;
}
static int create_shared(void **pointer, size_t size)
{
*pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if(*pointer == MAP_FAILED)
{
perror("mmap failed");
return -1;
}
return 0;
}
static void loop(void)
{
/* Set up signal handler. */
setup_signal_handler();
/* Check if we should stop or continue running. */
while(!map->stop)
{
sleep(2);
printf("map->stop: %d\n", map->stop);
}
return;
}
int main(void)
{
int rtrn;
pid_t pid;
printf( "entered Main\n");
rtrn = create_shared((void **)&map, sizeof(struct shared_map));
if(rtrn < 0)
{
printf("Can't create shared memory\n");
return -1;
}
map->stop = false;
pid = fork();
if(pid == 0)
{ //then child
printf( "child process\n");
loop();
_exit(0);
}
else if(pid > 0)
{ // then parent
int status;
printf( "parent process\n");
printf( "child Pid: %d\n", pid);
waitpid(pid, &status, 0);
return 0;
}
else
{ // else, fork failed
perror("fork failed");
return -1;
}
return 0;
}