creating child process from child [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm not entirely sure when I'm using fork() for child process process
there is child process creating other child process even though child process which is parent for other process (has status 0)?
#include <stdio.h>
int main()
{
printf("new proces");
if (fork() == 0) {
printf("child parent");
if (fork() == 0)
printf("child child");
}
printf("\n");
}
I'm confused because I'm not sure that when child proces invokes fork() it creates new proces or not?
because in this code
#include<stdio.h>
int main(){
printf(" do ");
if(fork()!=0) printf("ma ");
if(fork()==0) printf("to \n");
else printf("\n");
}
i have result like in this code there is child parent process which doesn't have status 0 and I don't know why beacuse it is child process of first parent process
do ma
do ma to
do to
do
not like this
do ma
do do to
to
child process invoking fork doesn't return 0 beause I have two ma not only one and i don't have idea why

Yes. The process creates a child, which then creates another child, becoming it's parent.
You can differentiate child and parent by using fork return number. From fork:
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the parent,
no child process is created, and errno is set appropriately.
You need to check fork() return value. If it returns 0, that means this process is a child. If it returns value greater then 0, then this process is the parent and the returned value is the childs process id.
Take a look at this program. I have added usleep calls to make processes print one after another:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
int main(){
// lets create a family!
pid_t grandpa_pid = getpid();
pid_t child_pid;
if ((child_pid = fork()) == 0){
pid_t parent_pid = getpid();
pid_t child_child_pid;
if ((child_child_pid = fork()) == 0) {
usleep(200);
printf("I am child and I will write third. My pid is %d, %d is my parent and %d is my parents parent, so my grandpa.", getpid(), parent_pid, grandpa_pid);
} else {
usleep(100);
// parent_pid = getpid()
printf("I am parent and I will write second. My pid is %d, %d is my child and %d is my parent.", getpid(), child_child_pid, grandpa_pid);
}
} else {
// grandpa_pid == getpid()
printf("I am grandpa and I will write first. My pid is %d and %d is my child.", getpid(), child_pid);
}
printf("\n");
}
Which produces the following output:
I am grandpa and I will write first. My pid is 5 and 6 is my child.
I am parent and I will write second. My pid is 6, 7 is my child and 5 is my parent.
I am child and I will write third. My pid is 7, 6 is my parent and 5 is my parents parent, so my grandpa.

Related

How to write a program that creates 2 parent processes and one child for each?

I'm not sure what does this code do.
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
for(int i=0; i<2; i++)
{
int pid=fork();
if(pid==0)
{
printf("child process \n");
printf("Child pid id [%d], parent pid is [%d]\n", (int) getpid(), (int) getppid());
} else if(pid>0)
{
int stats;
wait(&stats);
printf("parent process \n");
printf("Child pid id [%d], parent pid is [%d]\n", (int) getpid(), (int) getppid());
}
}
return 0;
}
I call fork() and assign it's value to variabe pid. Then we go to int stats, next line returns pid=0, then the program displays child process and then the parent process. It works pretty nice, but only when i<1. I thought that it is possible to do the same thing once again, but it's strange. fork() creates a new child process, so if it is used only once, if should create a child process, which parent is an IDE. Why am I wrong and what should I change to make 2 parents and 1 child for each, basically 4 processes?
I am not completely sure what you mean by "2 parents". In any case, you need to return the child so that they do not loop again:
printf("Child pid id [%d], parent pid is [%d]\n", (int) getpid(), (int) getppid());
return 0;
Otherwise you will have the children spawning other processes.

C program to get child process id's from just a parent id (minix) [duplicate]

This question already has an answer here:
Printing child processes given a pid (MINIX)
(1 answer)
Closed 6 years ago.
So given a process id passed to the system call, I need to return all child process ids. This must be written in C. I have used mproc to get the parent process of a child pid and list all processes from a certain index but cannot make the leap from that to this.
My code:
int do_getchildpids() {
// get pid from parameter
int ppid = m_in.m1_i1;
// Get the child pid of this process
pid_t cpid;
if (cpid == fork()) {
printf("Child pid for ppid %d is %d\n", ppid, getpid());
}
// ** Other attempt at this problem below **
// if mp_parent == ppid then print pid
int idx = 0;
int cpid = mproc[idx].mp_pid;
while (mproc[idx].mp_pid) {
idx++;
}
printf("Searching for children of %d...\n", ppid);
if (pid == 0) {
// for loop that gets the ppid, checks against given ppid
// prints out pid if true
if (cpid) {
// loop through proc table checking if ppid is equal to parameter passed
if (ppid == mproc[mproc[i].mp_parent].mp_pid)
printf("Child pid is %d.\n", getpid());
}
printf("Child pid is: %d.\n", getpid());
} else {
printf("Error, child pid was not set or is -1\n");
}
return 0;
}
This is a very janky solution, but if you're running linux and you want to get the children of a parent process you could use the linux pgrep command, either by using fork() and execv() or by a simple system() call. Then pipe the output to a file and read that file's contents
system("pgrep -P [parent_pid] 1>[outputfile]")
fp = fopen([outputfile], "r")
while (fscanf(fp, "%d", &child_pid) != EOF){
<add child_pid to a list you've made>
}
fclose(fp)
There's definitely a better way to do this though. Look into if it's possible to call ps or pgrep from a c program.

Creating too many processes and seems to only terminate parent processes

I have created a program that creates two child process for a parent process. The program is to output the parent's process showing its process ID and then the two child processes showing their IDs and the ID of the parent. The parent process is supposed to capture the child process using the wait() function after the program exits and print an output.
However, my program keeps creating parent processes and giving children to those processes. I only want one parent process for the two child processes. Inside the while loop is the wait() function that is supposed to check for the changed state of the children process and print " Child 'xxx' process terminated". Instead, it is terminating some of the parent processes and other random processes.
#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
pid_t cpid, cpid2, wpid;
int child = fork();
int child2 = fork();
int status;
if ((child = fork()) == 0){
child = cpid;
}
if((child2 = fork()) == 0){
child2 = cpid2;
}
else{
printf("I am the parent %d\n", getppid());
printf("I am the process %d created by %d\n", cpid, getppid());
printf("I am the process %d created by %d\n", cpid2, getppid());
while ((wpid = wait(&status)) > 0){
printf("Child process %d terminated\n", wpid);
}
}
return (0);
}
My output is showing me this
I am the parent 5764
I am the process 2 created by 5764
I am the process 6411548 created by 5764
I am the parent 13720
I am the process 2 created by 13720
I am the process 6411548 created by 13720
I am the parent 23612
I am the process 2 created by 23612
I am the process 6411548 created by 23612
I am the parent 15096
I am the process 2 created by 15096
I am the process 6411548 created by 15096
I am the parent 24276
I am the process 2 created by 24276
I am the process 6411548 created by 24276
I am the parent 13720
I am the process 2 created by 13720
I am the process 6411548 created by 13720
I am the parent 13720
I am the process 2 created by 13720
I am the process 6411548 created by 13720
I am the parent 5764
I am the process 2 created by 5764
I am the process 6411548 created by 5764
Child process 17016 terminated
Child process 18584 terminated
Child process 13984 terminated
Child process 8480 terminated
Child process 10816 terminated
Child process 21968 terminated
Child process 23388 terminated
Child process 11452 terminated
Child process 2776 terminated
Child process 19328 terminated
Child process 17116 terminated
Child process 18352 terminated
Child process 24276 terminated
Child process 15096 terminated
Child process 5764 terminated
Once you fork(), both the child and the parent are calling fork() again if you want to call fork() in the parent process only, check the return value before forking again.
int child = fork();
// This will be called by both, the child and the parent
int child2 = fork();
when fork() returns it returns the child PID in the parent and 0 in the child.
Start by reading the fork man page as well as the getppid / getpid man pages.
From fork's documentation:
On success, the PID of the child process is returned in the parent's
thread of execution, and a 0 is returned in the child's thread of
execution. On failure, a -1 will be returned in the parent's context,
no child process will be created, and errno will be set appropriately.
if ((child = fork()) == 0){
printf(" %u and %u", getpid(), getppid());
} else{ /* avoids error checking*/
printf("Parent - %u ", getpid());
}
The first child you fork() is forking the second child and also you're not handling else for the first fork()
#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
pid_t cpid, cpid2, wpid;
int child = fork();
int child2 = fork();
int status;
if ((child = fork()) == 0){
child = cpid;
}
else {
if((child2 = fork()) == 0){
child2 = cpid2;
}
else{
printf("I am the parent %d\n", getppid());
printf("I am the process %d created by %d\n", cpid, getppid());
printf("I am the process %d created by %d\n", cpid2, getppid());
while ((wpid = wait(&status)) > 0){
printf("Child process %d terminated\n", wpid);
}
}
The way you're doing it, the first child is forking it's own child which defines a handler for the case where the returned PID != 0. So you will spawn two of the second child and handle the parent case twice.

Parallel processing and synchronization using semaphores in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Questions:
Are my processes running in parallel?
I want six processes running in parallel.
How can I sync these processes (parent with five child processes) using semaphores, in an infinite loop? So the output would be: 1 2 3 4 5 reset 1 2 3 4 5 reset etc...
Any simple and understanding semaphore documentation?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
parentWithFiveChildren()
{
printf("1 "); //Parent
fflush(stdout);
int i, status;
for (i = 2; i < 7; i++)
{
sleep(1);
if (fork() == 0) //Child Processes
{
if (i == 6)
{
printf("reset ");
fflush(stdout);
exit(0);
}
printf("%d ", i);
fflush(stdout);
sleep(7);
exit(i); //Exiting child processes
}
}
while ((wait(&status)) > 0)
printf("\a");
return 0;
}
int main(void)
{
parentWithFiveChildren();
}
Output:
1 2 3 4 5 reset
1. Parallelism
No, the processes are not running in parallel (or, at least, they're only running in parallel transiently, and only two processes at a time), but that's only because:
The sleep(1) gives the parent process a long time (at least a second) doing nothing.
The child finishes and exits during that second.
Your printing code in the child is odd; there is effectively no difference between the i == 6 and the other operations. In main(), return 0; and exit(0); are practically the same — there can be differences, but they're obscure and not germane to your code.
You should #include <sys/wait.h> and you should collect the dead children's PID (and status); it would make things clearer to you.
You could also have the children report sleep for a while (say 7 seconds each). That would give you all the child processes 'running' (actually, sleeping) in parallel, and the parent then waits for the children to exit:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
printf("[PARENT] with pid %d\n", getpid());
fflush(stdout);
for (int i = 2; i < 7; i++) // Odd loop conditions, but not wrong
{
sleep(1);
if (fork() == 0)
{
printf("[CHILD] with pid %d from parent with pid %d\n", getpid(), getppid());
fflush(stdout);
sleep(7);
printf("[CHILD] with pid %d exiting with status %d\n", getpid(), i);
exit(i);
}
}
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("%d: child %d exited with status 0x%.4X\n", getpid(), corpse, status);
return 0;
}
Sample output:
$ ./test-forking
[PARENT] with pid 13904
[CHILD] with pid 13905 from parent with pid 13904
[CHILD] with pid 13906 from parent with pid 13904
[CHILD] with pid 13907 from parent with pid 13904
[CHILD] with pid 13908 from parent with pid 13904
[CHILD] with pid 13909 from parent with pid 13904
[CHILD] with pid 13905 exiting with status 2
13904: child 13905 exited with status 0x0200
[CHILD] with pid 13906 exiting with status 3
13904: child 13906 exited with status 0x0300
[CHILD] with pid 13907 exiting with status 4
13904: child 13907 exited with status 0x0400
[CHILD] with pid 13908 exiting with status 5
13904: child 13908 exited with status 0x0500
[CHILD] with pid 13909 exiting with status 6
13904: child 13909 exited with status 0x0600
$
An upgrade to the code would print the time with each line of output too.
2. Killing
Any of the processes (in the set created by the parent) can kill any other process (in the set) that it knows about, using the kill() system call. It really isn't clear whether you want the first child or the last child to kill the parent, or something else. If the first child kills the parent, the first child will be the only child (because of the delays). It also isn't clear why you want to send signals between the processes.
3. Looping
Yes, you could do something — the question is, what are you really after. Simply printing parent and child multiple times doesn't require multiple processes. If you want the parent to say "I'm here", and each child to say "I'm here" periodically, you need to have the children looping and sleeping, and the parent looping and sleeping after all the children have been created. Not hard to do.
question 3). ...Can I put main function in an infinite loop...?
Sure you can:
int main(void)
{
int c=0;
while((c != 'q') && (c != EOF))//loops until c == q (and c!=EOF)
{
c = getchar();//waits until stdin sees a "q", (i.e. from keyboard)
//An EOF (-1) or `q` will exit the loop
//any other input will allow execution flow to continue, 1 loop at a time.
//Add additional forking code here.
//for each loop, spawn a new thread.
//All secondary threads spawned will run parallel to other threads.
}
//exiting here will kill all threads (secondary and primary.)
return 0;
}
1) Yes, your parent process and child are running in parallel after fork,
You can see this by infinite looping child process and printing it's name while parent and other processes are doing the same.
2) Yes, here's how:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/types.h>
#include <signal.h>
int main()
{
pid_t pid;
int i = 0;
if ((pid = fork()) == 0)
{
if ((pid = getppid()) == -1)
{
fprintf(stderr, "child error: getppid()\n");
exit(1);
}
if (kill(pid, 9) == -1)
{
fprintf(stderr, "child error: kill()\n");
exit(1);
}
while (true)
{
printf ("child %d\n", ++i);
}
}
else if (pid == -1)
{
fprintf(stderr, "error: fork()\n");
return 1;
}
while (true)
{
printf("parent %d\n", ++i);
}
return 0;
}
3) If you need that specific pattern, you need interprocess communication and synchronization. Suggest this

Can a process have two PIDs?

I'm studying computer systems and I've made this very simple function which uses fork() to create a child process. fork() returns a pid_t that is 0 if it's a child process. But calling the getpid() function within this child process returns a different, nonzero pid. In the code I have below, is newPid only meaningful in the context of the program, and not to the operating system? Is it possibly only a relative value, measured against the pid of the parent?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
void unixError(char* msg)
{
printf("%s: %s\n", msg, strerror(errno));
exit(0);
}
pid_t Fork()
{
pid_t pid;
if ((pid = fork()) < 0)
unixError("Fork error");
return pid;
}
int main(int argc, const char * argv[])
{
pid_t thisPid, parentPid, newPid;
int count = 0;
thisPid = getpid();
parentPid = getppid();
printf("thisPid = %d, parent pid = %d\n", thisPid, parentPid);
if ((newPid = Fork()) == 0) {
count++;
printf("I am the child. My pid is %d, my other pid is %d\n", getpid(), newPid);
exit(0);
}
printf("I am the parent. My pid is %d\n", thisPid);
return 0;
}
Output:
thisPid = 30050, parent pid = 30049
I am the parent. My pid is 30050
I am the child. My pid is 30052, my other pid is 0
Lastly, why is the child's pid 2 higher than the parent's, and not 1? The difference between the main function's pid and its parent is 1, but when we create a child it increments the pid by 2. Why is that?
From fork man page :
Return Value
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately.
Fork does not returns the pid of the child, only in the parent. Therefore, the child process does not have two pids.
Try this
int main(int argc, const char * argv[])
{
pid_t thisPid, parentPid, newPid;
int count = 0;
thisPid = getpid();
parentPid = getppid();
printf("thisPid = %d, parent pid = %d\n", thisPid, parentPid);
if ((newPid = Fork()) == 0) {
count++;
printf("I am teh child. My pid is %d\n", getpid());
exit(0);
}
else
printf("I am the parent. My pid is %d, my child pid is %d\n", thisPid, newPid);
return 0;
}
Pids are one-per process. There will NEVER be more than 1 pid for a process - the internal data structures that handle the process in the OS only have a single PID field in them.
Beyond that, when you call fork() you are cloning the process that called fork, producing an exactly duplicate of it - all file handles, all memory, etc.. EXCEPT for its PID. That's why fork returns different values depending on if you're the child or parent process. This differing return values lets the program know if it's a child or a parent. The child gets 0, and can therefore know it's the child.
No, a pid is assigned to exactly one process at a time.
Process ids do not need to follow any rules when being assigned to processes. So if it looks as if a child pid is the increment of the parent's pid this is just luck.
By the pid of certain processes it is not possible to draw any conclusions regarding the processes relationship.
PIDs are not sequential on assignment (the actually follow no rules) and one process has only one PID at a time. Also there can never be two processes that share the same PID.

Resources