My goal from the code is the following:
-Generate a random number between a given range
-Make user guess the number using the child process
-Make the parent tell the user if guess should be higher/lower
-If guess is correct give a signal for the child to exit.
Current code:
int main() {
int randomnumber = 1+ rand() % 51;
int guess;
pid_t pid=fork();
bool signal=false;
if(pid<0){
printf("Fork failed");
}
if(pid==0){
printf("Enter your guess: \n");
}
while(1)
{
if(pid==0){
if(signal==true)
exit(0);
scanf("%d", &guess);
}
print("test1"); //put this for debugging purposes and only executed once instead of twice
if(pid>0){
print("test2"); //this doesn't execute so I can conclude that parent isn't executing for some reason
wait(NULL);//before adding this parent used to execute and I got an infinite amount of prints which is normal, adding it made the parent not execute
if(guess>randomnumber){
printf("Guess should be lower");
}
if(guess<randomnumber){
printf("Guess should be higher");
}
if(guess==randomnumber){
printf("WIN");
signal=true;
break;
}
}
}
return 1;
}
Any idea what I can do to synchronize both of them? Why doesn't the parent execute after adding the wait function, it should at least execute the parent before wait(NULL).
As some some users remarked in comments this cannot be done unless I implement inter-process communication or a shared memory.
Related
I want to write a C program that asks the user for an integer and stores it in a variable n. Then, the main process creates two
child processes (both must be children of the main process). One child exits successfully if n>10 and unsuccessfully
otherwise, whereas the other child exits successfully if n>20 and unsuccessfully otherwise. The main process must print
how many of its children ended successfully.
This is what I have so far.
#include <stdio.h>
void main (void)
{
int n;
printf("Give me a number: ");
scanf("%d", &n);
pid_t child_a, child_b;
child_a = fork();
if (child_a == 0) {
if (n>10) {
exit(1)
}else{
exit(0)
}
} else {
child_b = fork();
if (child_b == 0) {
if (n>20){
exit(1)
}else{
exit(0)
}
} else {
/* Parent Code */
}
}
}
But how do I count how many child processes end successfully?
You need to use wait() command, system call wait() function blocks the calling process until one of its child processes exits or a signal is received.
int status;
pid_t pid = wait(&status);
printf("Exit = %d, child = %d\n", WEXITSTATUS(status), pid);
see example at:
fork() and wait() with two child processes
and 2nd example using wait() and WEXITSTATUS()
Linux fork() and wait()
Also more about what happen with multiple cores scheduling of processes:
fork() and wait() calls
I want to make two parallel working forks and in the end wait for them to finish.
for (int i = 0; i < 2; i++) {
pid_t pid = fork();
if(pid < 0) {
fprintf(stderr,"Cannot fork!");
exit(EXIT_FAILURE);
}
else if(pid == 0) {
switch(i)
{
case 0:
//first child
exit(EXIT_SUCCESS);
break;
case 1:
//second child
exit(EXIT_SUCCESS);
break;
}
break;
}
else {
//parent
}
}
The problem is that the main program terminates before the child ones. If I add wait(0) to the else parent part it waits to every process so they don't work at the same time but one by one.
I assumed that I can simply put the wait() or waitpid() after the loop but that's not working either. I thought that after the fork the parent continues normally so why doesn't it wait when the wait() is outside the loop and if-else structure?
Sorry for bothering and thanks in advance.
If you add wait(NULL) inside the else parent part, the parent-process will indeed wait for the first child-process to return before it creates the second.
If you add wait(NULL) after the loop, the parent process will wait only once, for the first child-process that will return.
If you want all children-processes to run at the same time, you need a second loop, where the parent-process will use wait() as many times as needed to collect the exit status of every child-process.
In your case, there are 2 children-processes, thus 2 wait() system calls are enough. The loop to add would be like this (I also added a printf so that you can observe it on your stdout):
for (i = 0; i < 2; i++) {
wait(NULL);
printf("My child No %d died.\n", i);
}
i've been making google searches about my question for 2 days but im done with it. I have very basic information about process management, fork etc. I've been told to create some children processes of a same parent process and send them seeds by using pipes so they can produce some random numbers, all for their own. But I'm stuck at creating children processes.
for (i = 0; i < NUM_PLAYERS; i++) {
/* TODO: spawn the processes that simulate the players */
switch(pid = fork()){
case -1: // ERROR
exit(EXIT_FAILURE);
case 0: // CHILD PROCESS
printf("My parent id is %d \n", getppid());
exit(EXIT_SUCCESS);
default: // PARENT PROCESS
wait(NULL);
}
}
When I go with this code, parent creates NUM_PLAYERS children but I can't seem to use them in another for loop since they had terminated at the end of the case 0. When I just remove exit(EXIT_SUCCESS); line, so many processes are created and they have all different parents. So my question is, how to properly create children processes and use them later?
If you remove exit(EXIT_SUCCESS) your child will continue executing where it was forked, IE it will go back to the close brace of the for() loop, and generate new children itself. What do you want the child to do? You should make it do that, and then do exit(EXIT_SUCCESS) and not let it return to to the for() loop.
Note also that wait() will only wait for one process to quit.
void do_something()
{
//create random numbers or whatnot
}
//...........
case 0: // CHILD PROCESS
printf("My parent id is %d \n", getppid());
do_something();
exit(EXIT_SUCCESS);
You'll need the parent to wait on the children in a later loop. The way you have it will block until a single child returns. You want to create multiple children before then waiting on them.
Note that you still have to add the pipe logic so parent/child can communicate.
EDIT
This is the broad outline of what you need to do:
for (i = 0; i < NUM_PLAYERS; i++) {
/* TODO: spawn the processes that simulate the players */
switch(pid = fork()){
case -1: // ERROR
exit(EXIT_FAILURE);
case 0: // CHILD PROCESS
printf("My parent id is %d \n", getppid());
exit(EXIT_SUCCESS);
}
}
// only the parent will ever execute below here
for (i = 0; i < NUM_PLAYERS; i++)
{
while ( /* read each child's pipe*/)
{
//do something with data
}
}
for (i = 0; i < NUM_PLAYERS; i++)
wait(NULL);
return(0);
I have written a program where I have created a child process. Both the parent process and child process do calculation in two parts- parent_part1 , parent_part2 and child_part1, child_part2.
My aim is to run the (parent_part1,child_part1,parent_part2 ,child_part2) sequence for let us say 5 times. For this purpose I have used while(var_child++<10) and while(var_par++<10) and successfully achieved it.
Now, I will define ONE SUCCESSFUL calculation is execution of (parent_part1,child_part1,parent_part2 ,child_part2) sequence for 5 times and display the final correct value.
I want to find such 100 SUCCESSFUL calculation and for the same purpose I have used OUTER loop (i.e., while(t1++<100) ), but I am not getting the SUCCESSFUL calculation for 100 times , sometimes I got 40 SUCCESSFUL result, and hanged after parent_part1 or parent_part2 or child_part1 or child_part2 etc. and some other times I got 20 or 95 SUCCESSFUL result, and hanged after parent_part1 or parent_part2 or child_part1 or child_part2 etc.
What is the reason and how to overcome this ?
Thank you in advance . The program is as below.
#include<stdio.h>
#include<signal.h>
int flagp=0,flagc=0,var_child=0,var_par=0;
void write_child()
{
if(flagc==0)
{
/* do some computation here*/
printf("Child_part1 \n");
flagc=1;
}
else
{
/* do some computation here*/
flagc=0;
printf("Child_part2 \n");
}
}
void write_parent()
{
if(flagp==0)
{
/* do some computation here*/
printf("Parent_part1 \n");
flagp=1;
}
else
{
/* do some computation here*/
printf("Parent_part2 \n");
flagp=0;
}
}
int main(int ac, char **av)
{
printf("Starting...\n");
int t1=0;
pid_t childpid = fork();
printf("childpid=%d,getppid()=%d \n",childpid,getppid());
while(t1++<100)
{
var_child=0;
var_par=0;
if ( childpid == 0 )
{
// child process
printf("\n\nt1=%d ",t1);
while(var_child++<10)
{
kill(getppid(), SIGCONT); //sending singal to parent
signal(SIGCONT, write_child);
pause();
}
}
else
{
//parent process
printf("\n\nt1=%d ",t1);
while(var_par++<10)
{
kill(childpid, SIGCONT); //sending singal to child
signal(SIGCONT, write_parent);
pause();
}
} // end of else
}
return 0;
}
Are you sure this logic is correct?
while(var_par++<10)
Apart from that, you are not catching the signal from the parent process. you are creating a lot of zombie processes when the child terminates and by killing the parent from child, you are creating orphans. Both will take system resources and might hit the upper limit on consecutive executions. Try catching the signal and see how it behaves.
I am tryimg to write a C program that will search an array of integers for another given integer. However, to speedup the search, the search is done in parallel by two child processes. The parent process reads in the number of integers, and then the integers in an array. It also reads in the integer to be searched. It then creates two child processes. The first child process searches the first half of the array, and the second child process searches the second half. If the integer is found, its index in the array is sent to the parent through a pipe. If it is not found, a -1 is sent to the parent through a pipe. The parent waits for both child processes to finish and then prints an appropriate message.
I have consulted some books and this is what i came up with. There is a small problem though...the two child processes are running one after the other rather than parallel. what changes should i make?
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include <string.h>
void main ()
{
int i,status,num1,num2,num3,num4, fd1[2], fd2[2];
int a[1000];
char b[5],c[5],d[5],e[5];
pid_t pid1,pid2;
printf("\n\n\nEnter how many numbers - ");
scanf("%d",&num1);
//printf("\n\nEnter the %d numbers below -\n",num1);
for (i=0;i<num1;i++)
{
printf("%d : ",i);
scanf("%d",&a[i]);
}
printf("\n\nEnter the number to search - ");
scanf("%d",&num2);
pipe(fd1);
pipe(fd2);
pid1=fork();
if (pid1==0)
{
printf("this is the child 1\n");
for (i=0;i<(num1/2);i++)
{
if (a[i]==num2)
{
printf("found by process 1\n");
sprintf(b,"%d",i);
sprintf(c,"%d",-1);
write(fd1[1],&b,4);
write(fd2[1],&c,4);
//kill(0,1);
break;
}
printf("%d\n",a[i]);
}
_exit ( EXIT_FAILURE ) ;
}
else
if (pid1>0)
{
pid2=fork();
if (pid2==0)
{
printf("this is the child 2\n");
for (i=(num1/2);i<num1;i++)
{
if (a[i]==num2)
{
printf("found by process 2\n");
sprintf(b,"%d",-1);
sprintf(c,"%d",i);
write(fd1[1],&b,4);
write(fd2[1],&c,4);
//kill(0,1);
break;
}
printf("%d\n",a[i]);
}
_exit(EXIT_FAILURE);
}
}
if (waitpid (pid1, &status, 0)>0 && waitpid (pid2, &status, 0)>0)
{
read(fd1[0],d,4);
read(fd2[0],e,4);
num3=atoi(d);
num4=atoi(e);
if (num3>0) printf("value of i is %d\n",num3);
if (num4>0) printf("value of i is %d\n",num4);
}
}
Your code is fine, but remember that processor time is given out in rather large slices. That is, a short computation is often finished before the other process has even received a processor time slice. Insert a few calls to sleep into your loops, and you will see the concurrency.
Are we sure your system has more than one core? If it has only one processor, the processes will run one after the other anyway.