int main()
{
int i;
int status;
for (i = 0; i < 4; i++) {
if(fork() == 0){
sleep(1);
}
}
printf("This is the end.\n");
return 0;
}
I need to change the code so that exactly 4 child processes will be created. I have tried a few things but Im not sure how to do it.
You have to prevent the child processes from creating new child processes. To do so, just exit the loop in a child process.
for (i = 0; i < 4; i++) {
if(fork() == 0) {
// Only the child process will execute this
sleep(1);
break;
}
}
Related
I was given this particular task:
Using SIGCONT, SIGSTOP, and SIGCHLD, write a program that accepts
through argv[] a list of commands (none of them has arguments) and
runs the commands in a round-robin style, alternating commands in
1-second intervals.
To achieve it, I tried this:
int dead_children = 0;
int nr_processes;
void inc_dead () {
printf("I, %d, died\n", getpid());
dead_children++;
if (dead_children == nr_processes)
_exit(0);
}
int main (int argc, char *argv[]) {
int pids[argc - 1];
nr_processes = argc - 1;
signal(SIGCHLD, inc_dead);
for (int i = 1; i < argc; i++) {
pid_t pid;
if ( (pid = fork()) == -1 ) {
perror("fork");
return EXIT_FAILURE;
}
if ( !pid ) {
pause();
execlp(argv[i], argv[i], (char *) NULL);
perror("exec");
_exit(1);
}
pids[i - 1] = pid;
}
while (dead_children < nr_processes)
for (int j = 0; j < argc - 1; j++) {
kill(pids[j], SIGCONT);
sleep(1);
kill(pids[j], SIGSTOP);
}
return EXIT_SUCCESS;
}
I tried to run this code with very simple program that would allow me to verify task's correctness:
int main (void) {
int i = 5;
while (i-- > 0) {
printf("This is %d saying HI!\n", getpid());
sleep(1);
}
return EXIT_SUCCESS;
}
However, this does not work. I noticed that after creation, child processes never left pause() instruction, even though parent is sending a SIGCONT. Any thoughts on how to achieve the goal?
I'm implementing a simple parent/child process program using fork. My goal is to create a user input number of child processes from a single parent and store their PIDs in a dynamic array. I manage to create the child processes (I think) using fork and store their PIDS. However, when I store the PIDs, I also store the 0 PID and what I believe another PID related to the processes yet this number is quite bigger than the child and parent.
How come this happens when clearly this is only done inside the parent process?
void createProcesses(int nProcess) {
int i;
int PID;
processIDS = calloc(nProcess, sizeof(long));
printf("*****Creating Processes*****\n");
printf("Parent Process: PID %d\n", getpid());
for (i = 0; i < nProcess; i++) {
PID = fork();
if (PID == 0) {
printf("Child Process: PID %d\n", getpid());
while(1){}
}
else if(PID != 0) {
// sleep(3);
// printf("Number of child processes created: %d\n", nProcess);
// updateProcessList();
*(processIDS + i) = PID;
printf("%d\n", PID);
}
}
for(i = 0; i < sizeof(processIDS); i++) {
printf("%ld\n", *(processIDS + i));
}
while(1) {
sleep(5);
updateProcessList();
}
}
processIDS is a long * global variable.
The problem is here:
for(i = 0; i < sizeof(processIDS); i++) {
printf("%ld\n", *(processIDS + i));
}
Because processIDS is a pointer, it's size is the size of a long *, probably 4 or 8, which is not what you want. If the value of nProcess is less than this, you'll be reading off the end of the dynamically allocated array, invoking undefined behavior.
You know there are nProcess processes created, so use that for your loop test:
for(i = 0; i < nProcess; i++) {
printf("%ld\n", *(processIDS + i));
}
I'm trying to write a small program that forks processes from a single parent. Currently my code does this a few times but then the children create more child processes, which I want to eliminate.
int main() {
pid_t c;
for (int i = 0; i < 5; i++) {
c = fork();
if(c < 0) {
perror("fork");
exit(1);
}
else if( c > 0 ) {
printf("parentID = %d, childID = %d\n", getppid(i), getpid(i));
}
}
}
I'm not sure how to modify it so that fork is only forking from the parent though.
EDIT: thanks for the help, got the solution:
int main() {
pid_t c;
for (int i = 0; i < 5; i++) {
c = fork();
if(c < 0) {
perror("fork");
exit(1);
}
else if( c > 0 ) {
printf("parentID = %d, childID = %d\n", getppid(i), getpid(i));
}
else {
exit(0);
}
}
}
nothing in the posted code is recognizing the child (0 == pid)
so a child hits (and skips) the two 'if' statements.
hits the end of the loop,
branches back to the top of the loop, calls fork()....etc.
Suggest: adding
elseif( 0 == pid )
{ // then child ...
exit( EXIT_SUCCESS );
}
The child process does not enter any part of the if block, and just loops back to the top of the for loop creating more children. Also, the if (n > 0) block gets run for the parent, not the child, since fork returns 0 to the parent and the child's pid to the parent.
Change if (n > 0) to if (n == 0), and call exit() at the bottom of the block to prevent the child from continuing. Also, getpid() and getppid() don't take any arguments.
int main() {
pid_t c;
for (int i = 0; i < 5; i++) {
c = fork();
if(c < 0) {
perror("fork");
exit(1);
}
else if( c == 0 ) {
printf("parentID = %d, childID = %d\n", getppid(), getpid());
exit(0); // <-- here
}
}
}
I'm trying to use the multiple fork() calls to create several children with different task
I found a code on
Multiple child process
Which is really close for what I want , yet I couldn't fully understand it
pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild != 0)
{
// In parent
secondChild = fork();
if(secondChild != 0)
{
// In parent
}
else
{
// In secondChild
}
}
else
{
// In firstChild
}
My questions are:
How many process have been created (I assume that we have 4 since it's 2 forks!)?
In this part of the code
firstChild = fork();
if(firstChild != 0)
{
// In parent
secondChild = fork();
if(secondChild != 0)
{
// In parent
}
Does "//in parent" mean both of them are the same process (they have the same PID when I tried to test it).
How can I create 3 children using 2 forks?( I can draw the tree that ends with 4 leaves 3 of them are children and 1 parent)
Thank you (please feel free to tell me if I'm not totally getting the Fork concept)
How many process have been created (I assume that we have 4 since it's 2 forks!)?
Depending on the result of your forks it should be 0 to 2. Probably 2 if nothing goes wrong. There's a parent process that forks 2 children processes.
Does "//in parent" mean both of them are the same process (they have the same PID when I tried to test it).
Yes. In your case the code is checking for a return value of fork being non zero. That's not a very good idea since it covers 2 distinct cases:
It could be less than zero indicating an error, or ...
It could be greater than zero indicating to the parent the pid of the newly spawned process
Anyway ... considering all goes well and both the forks succeed, you will end up with a parent process having 2 different children.
How can I create 3 children using 2 forks?( I can draw the tree that ends with 4 leaves 3 of them are children and 1 parent
Something like this should do the trick:
firstChild = fork();
if (firstChild < 0) {
exit(EXIT_FAILURE);
perror("fork");
}
secondChild = fork();
Notice that by not checking the return value of fork() any more I'm getting a child process continuing execution at the same place as the parent. So the next fork will actually be executed by both the parent and the children each spawning a new process. So I'll get something like this ...
parent─┬─child1───(child1's child)
└─child2
I can't think of any way you can get this with only 2 forks though:
parent─┬─child1
├─child3
└─child2
Note: It's customary on stackoverflow to only limit yourself to one question per topic.
The following code shows how to create 4 process (1 parent 3 children) with only 2 forks
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int *list;
void calculate_average(int );
void calculate_maximum(int);
void calculate_minimum(int);
void calculate_average(int count)
{
int i, total = 0;
for (i = 0; i < count; i++)
total += list[i];
double average = total / count;
printf("average is %f\n",average);
}
void calculate_maximum(int count)
{
int i;
int maximum = list[0];
for (i = 1; i < count; i++)
if (list[i] > maximum)
maximum = list[i];
printf("maximum is %d\n",maximum);
}
void calculate_minimum(int count)
{
int i;
int minimum = list[0];
for (i = 1; i < count; i++)
if (list[i] < minimum)
minimum = list[i];
printf("minimum is %d\n",minimum);
}
int main(int argc, char *argv[])
{
pid_t pid, pid1;
int num_of_args = argc-1;
int i;
/* allocate memory to hold array of integers */
list = malloc(sizeof(int)*num_of_args);
for (i = 0; i < num_of_args; i++)
list[i] = atoi(argv[i+1]);
printf("The %d number of input ingeters are\n",num_of_args);
for (i = 0; i < num_of_args; i++)
printf("%d\n",list[i]);
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { /* P2 */
pid1=getppid();
calculate_average(num_of_args);
}
else { /* P1 */
pid1=getpid();
wait(NULL);
}
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { /* could be either P3 or P4 */
if (getppid() == pid1) { /* P3 */
calculate_minimum(num_of_args);
}
else { /* P4 */
calculate_maximum(num_of_args);
}
}
else {
wait(NULL);
}
return 0;
}
Note that one of the children will be a parent for a grandchild
I am trying to communicate with children processes and make them sort a part of a list. My problem is children processes read everything but do nothing after it.
int main(int argc, char *argv[]){
int i;
int num_children;
pid_t pid;
num_children= 3;
int fd[num_children][2]; //PIPES
for (i=0; i<num_children; i++)
{
if (pipe(fd[i]) == -1)
{
printf("couldnt create the pipe\n");
exit(EXIT_FAILURE);
}
}
for (i=0; i<num_children; i++)
{
pid = fork();
if (pid == -1)
{
printf("couldnt create child process %i\n",i);
exit(EXIT_FAILURE);
}
if (pid == 0)
{ //this is child process
close(fd[i][1]); //closing fd[1] the write end of the pipe
int received;
node *list = NULL;
while ( read(fd[i][0], &received, sizeof(int)) > 0)
{
list = insert(list, received);
printf("Process %i got the number: %i\n",i,received); //this part is working perfect
}
printf("Im process %i here is my list: \n",i); //i couldnt get any output from here
printList(list);
close(fd[i][0]);
exit(EXIT_SUCCESS);
}
}
for (i=0; i<num_children; i++) //closing the read end of pipe for parent
{
close(fd[i][0]);
}
int number;
int mod;
FILE *fileIn = fopen ("<file directory>","r");
while(fscanf(fileIn, "%i", &number)>=0)
{
mod = number % num_children;
write(fd[mod][1], &number, sizeof(int));
}
for (int i=0; i<num_children; i++)
{
if(close(fd[i][1])==0)
{
printf("cant close the pipe");
//tried to catch errors, but pipes are closing with no problem i think
}
}
return 0;
I tried to see if children process wait in the while(read) loop, but when i close the write end of pipes from the parent process they should leave the loop.
You're probably thinking that some specific pipe[2] is shared by the parent and it's respective child process. That's true ... However it is also shared by all the other children processes you create along the way - and because it's opened, those other children processes also inherit it as opened.
Doing this at the beginning of your child pid check worked for me:
if (pid == 0) {
int j;
for (j = 0; j < num_children; j++) {
if (j != i) {
close(fd[j][0]);
close(fd[j][1]);
}
}
...
}
I suspect that the reading from the pipe via:
while ( read(fd[i][0], &received, sizeof(int)) > 0)
is being blocked/haulted until data is available on the pipe. If so, this would explain the lack of response from your code after this point.