Not sure why 1 printf statement prints twice - c

UPDATE
I thought this code block was giving me an error printing a printf statement out twice, but I commented out everything in my code BESIDES this and it worked just fine! What seems to be the issue then is the work I am doing with process IDs.
Here is the entire code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid, pid1;
int n;
int temp;
int stop = 1;
if (argc == 1) {
fprintf(stderr,"Usage: ./a.out <starting value>\n");
return -1;
}
n = atoi(argv[1]);
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) { /* child process */
pid1 = getpid();
printf("child: pid = %d\n", pid);
printf("child: pid1 = %d\n", pid1);
}
else { /* parent process */
pid1 = getpid();
printf("parent: pid = %d\n", pid);
printf("parent: pid1 = %d\n", pid1);
wait(NULL);
}
while (n!=1) {
if (n%2 == 0) {
printf("%d, ", n);
temp = (n/2);
n = temp;
}else {
printf("%d, ", n);
temp = (3*n+1);
n = temp;
}
}
printf("1\n");
return 0;
}
The output I'm expecting is something like:
parent: pid = 1444
parent: pid1 = 1443
child: pid = 0
child: pid = 1444
8, 4, 2, 1
But instead I get this Output:
parent: pid = 1444
parent: pid1 = 1443
child: pid = 0
child: pid = 1444
8, 4, 2, 1
8, 4, 2, 1
Might a child a parent process be printing out the sequence a second time?

Yes, once the parent process has wait()ed on the child process, it continues down the code path and prints the sequence.
What you want is:
// ....
else if (pid == 0) { /* child process */
pid1 = getpid();
printf("child: pid = %d\n", pid);
printf("child: pid1 = %d\n", pid1);
while (n!=1) {
if (n%2 == 0) {
printf("%d, ", n);
temp = (n/2);
n = temp;
}else {
printf("%d, ", n);
temp = (3*n+1);
n = temp;
}
}
} else { /* parent process */
pid1 = getpid();
printf("parent: pid = %d\n", pid);
printf("parent: pid1 = %d\n", pid1);
wait(NULL);
}

After
wait(NULL);
You need an exit/return. The parent has done its job of bringing up the child and is done

Related

How do I make it so that processes are created parallel to each other rather than one after another?

I need help in modifying this code. Right now, it creates a process, and then waits for its termination. After which, another process is created, and then it waits for its termination. I want to modify it so that it creates both processes at the same time and executes them parallel to each other. The code is:
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char * argv[]) {
pid_t pid;
int status;
pid = fork();
if (pid != 0) {
while (pid != wait( & status));
} else {
sleep(5);
exit(5);
}
pid = fork();
if (pid != 0) {
while (pid != wait( & status));
} else {
sleep(1);
exit(1);
}
}
Here's code that should do the job:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid = fork();
if (pid != 0)
printf("Child 1 PID = %d\n", pid);
else
{
sleep(5);
exit(5);
}
pid = fork();
if (pid != 0)
{
printf("Child 2 PID = %d\n", pid);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child %d exited with status 0x%.4X\n", corpse, status);
}
else
{
sleep(1);
exit(1);
}
return 0;
}
One time when I ran it, I got the output:
Child 1 PID = 49582
Child 2 PID = 49583
Child 49583 exited with status 0x0100
Child 49582 exited with status 0x0500
If you preferred, you could move the wait() loop and its variable declarations after the if structures and immediately before the return 0; at the end. That would give you better symmetry. You could even wrap up the child creation phase into a function called twice:
static void procreate(int kidnum, int naptime)
{
int pid = fork();
if (pid != 0)
printf("Child %d PID = %d (nap time = %d)\n", kidnum, pid, naptime);
else
{
sleep(naptime);
exit(naptime);
}
}
and then in main() you'd just have two calls to procreate() and the wait loop:
int main(void)
{
procreate(1, 5);
procreate(2, 1);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child PID %d exited with status 0x%.4X\n", corpse, status);
return 0;
}

fork() 4 children in a loop

The goal is to try and fork 4 children in a loop, but I'm not sure how to properly do that. This is what I have so far. I tried to draw it out and I think I'm not waiting to reap the child properly. And I create like 2 children every iteration. So, 8 children in total.
void main() {
int i = 0;
pid_t pid;
int status;
for(i = 0; i < 4; i++) {
pid = fork();
if(pid == 0) {
/* Child Process */
fork();
exit(0);
} else {
/* Parent Process */
wait(&status);
printf("At i = %d, process %d is terminated.\n", i, pid);
}
}
}
Creating four children processes from the same parent process can be achieved by forking once on each iteration of the for loop:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
for (int i = 0; i < 4; i++) {
pid_t pid = fork();
if (pid == 0)
exit(0); // child process
// parent process
wait(NULL);
printf("At i = %d, process %d is terminated.\n", i, pid);
}
}
However, you probably want the parent process to wait for the children after it has created all of the four children, because you usually want the children to do something before exiting and concurrently with the other children:
int main() {
// create the four children processes
for (int i = 0; i < 4; i++) {
pid_t pid = fork();
if (pid == 0) {
// child process
// ... do some stuff ...
exit(0);
}
}
// wait for the four children processes to finish
for (int i = 0; i < 4; i++) {
pid_t pid = wait(NULL);
printf("Process %d is terminated.\n", pid);
}
}

Finding the level of a child process in a process tree

I've been trying to create a process tree using fork() and print each child's level (0 for base process, 1 for its child, 2 for its grandchild etc.) in the tree. The code below only works for depth 0 and 1. Any idea how I can improve it?
Thanks.
#include <stdio.h>
#include <unistd.h>
int i;
int main()
{
pid_t baseID = getpid();
printf("Base Process ID: %d, level: 0 \n", baseID);
for (i = 0; i < 3; i++) {
int level = 1;
pid_t pid;
pid = fork();
if (pid == 0) {
pid_t childID = getpid();
pid_t parentID = getppid();
if (parentID == baseID) {
level = 1;
}
else {
// do something for grandchildren here
level++;
}
printf("Process ID: %d, Parent ID: %d, level: %d \n", getpid(), getppid(), level);
}
else {
wait(NULL);
}
}
return 0;
}
The intended process tree is the following:
0
|->1
| |->2
| | |->3
| |
| |->2
|
|->1
| |->2
|
|->1
So to be able to print the level of each process, we should just initialize the level variable to 0 outside the main for loop and just increment its value each time a child process is created.
The following code will print the level of each child process as expected:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t baseID = getpid();
printf("Base Process ID: %d, level: 0 \n", baseID);
int level = 0;
for (int i = 0; i < 3; i++) {
pid_t pid = fork();
if (pid == 0) { // Child
pid_t childID = getpid();
pid_t parentID = getppid();
level++;
printf("Process ID: %d, Parent ID: %d, level: %d \n", getpid(), getppid(), level);
} else { // Parent
wait(NULL);
}
}
return 0;
}

Why the child process is not executed?

I have the following piece of code:
int main() {
int n = 1;
if(fork() == 0) {
printf("child");
n = n + 1;
exit(0);
}
n = n + 2;
printf("%d: %d\n", getpid(), n);
wait(0);
return 0;
}
The problem is that I don't understand why the child process is not executing.
The child process is executing only if i set sleep(1) in the parent process
Thanks in advance.
It is getting executed and it should be outputting the text. No newlines should be necessary:
https://ideone.com/a1tznH
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int n = 1;
if(fork() == 0) {
printf("child");
n = n + 1;
exit(0);
}
n = n + 2;
printf("%ld: %d\n", (long)getpid(), n); //this is how you should print pids
wait(0);
return 0;
}
Example output:
child23891: 3
Perhaps you didn't notice the child text was at the beginning of your next prompt:
18188: 3
child[21:17] pskocik#laptop: $
The child is executed but two processes are trying to write on the same FD - STDOUT (File Descriptor).
If you want to see the result, put "\n" in printf of the child.
int main() {
int n = 1;
if(fork() == 0)
{
printf("child\n");
n = n + 1;
exit(0);
}
n = n + 2;
printf("%d: %d\n", getpid(), n);
wait(0);
return 0;
}
Try
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("fail to fork");
}
else if (pid == 0)
{
printf("running child");
exit(0);
}
else
{
print("running parent");
wait(0);
print("child done");
}
return 0;
This is the basic structure of a program I wrote recently which works. Not totally sure why yours didn't work though.

Function to create n child processes

int proc_create(int n)
{
int pid;
n = n+1;
printf("The parent process id: %d\n", getpid());
while(1)
{
if(pid=fork() < 0){
perror("Fork Failed!");
exit(1);
}else{
printf("The child process ID is: %d\n", pid);
}
}
}
I have written the above function that will create n child processes and each child processes will print out it's own child id. Can someone tell me the flaws and how i can improve the above function.
n is a local variable, so you just do n + 1 which doesn't change anything.
It creates infinite child processes, because the fork is inside a while(1) loop
int *proc_create(int n) {
int *childs = malloc(sizeof *childs * n);
printf("The parent process id: %d\n", getpid());
for (int i = 0; i < n; i++) {
int pid = fork();
if (pid < 0) {
perror("Fork Failed!");
exit(1);
} else if (pid == 0) {
return NULL;
} else {
childs[i] = pid;
printf("The child process ID is: %d\n", pid);
}
}
return childs;
}
This process spawn N children, when they return from proc_create() they will return NULL. The parent will return an array with the pids of its N children.

Resources