Fork(), one process doesn't terminate? - process

I have never get this before; i'm doing a simple program: a father process which creates child processes, and after it terminates; this is the code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int child(pid_t pid)
{
printf("process %d is terminating\n",pid);
exit(EXIT_SUCCESS);
}
int main()
{
int i;
for(i = 0; i < 2; i++){
if(fork() == 0)
child(getpid());
}
printf("father, pid=%d terminated\n",getpid());
/*if(wait(NULL) == -1)
perror("wait");*/
exit(EXIT_SUCCESS);
}
when i run, all processes printed, but one process, i think father but i'm not sure, doesn't terminate because terminal is active(doesn't appear $);
insted, if i insert commented line with wait, program runs correctly; why this?
terminal output

If you look at the last run in the screen capture, you'll see "process 8429 is terminating" after the terminal prompt has been printed to the screen.
What appears to be happening is your "father" process happens to exit first, and your shell then outputs the prompt. Then, in the last case, the child process (PID 8429) printed its output and then exited.
So it is terminating, but sometimes the child process doesn't terminate until after the parent process exited and your shell process has already printed the prompt.
Just hit "enter" again when it does that, and you should see a proper shell prompt. Or even enter a command, and it should run normally.

Related

Why zombie process disappears from htop if i don't call waitpid()?

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid = fork();
if (pid == 0)
{
printf("I am Child\n");
exit(0);
}
printf("I am Parent\n");
while(1);
}
Here is what happens on my Linux when i run this code: zombie process shows up in htop for a second and then just disappears.
I tried setting signal handler in parent:
void callback(int signum)
{
return;
}
int main()
{
int pid = fork();
if (pid == 0)
{
printf("I am Child\n");
exit(0);
}
printf("I am Parent\n");
signal(SIGCHLD, callback);
while(1);
}
But nothing changed. Why my zombie process disappears from htop?
P.S.: compiled with no optimization
Update: it doesn't show up in htop but does show up in top. Seems like a bug to me. I vote for deletion of this question.
The process disappears from htop because by default it sorts by CPU usage, so a zombie process will be so far down the list that it's off the screen.
It happens after one second because that's the default htop refresh interval.

Unable to set scheduling policy using sched_setscheduler() function?

I am new to OS programming. So, I wrote this code to change the scheduling policy of a background process, whose process ID I supply through a command line argument, but the sched_setscheduler() function fails, giving an error, "Function not implemented"
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
struct sched_param param;
param.sched_priority = 80;
int pid = atoi(argv[1]);
int policy = sched_getscheduler(pid);
printf("Current policy: %d\n", policy);
if(sched_setscheduler(pid, SCHED_FIFO, &param) == -1){
perror("Scheduler policy cannot be set");
}
int new_policy = sched_getscheduler(pid);
printf("New policy: %d\n", new_policy);
}
Can someone please tell me why this happening? Thanks.
So, I wrote this code to change the scheduling policy of a background process, whose process ID I supply through a command line argument
Here is the problem. sched_setscheduler(2) gets a thread id not a process id. For single thread processes PID and TID coincide, but in multi-threaded processes every thread has its own TID.
The fact that the argument is named pid and is of type pid_t might be misleading and even some old man-pages of sched_setscheduler(2) wrongly talk about processes, but this function is actually about threads.

How to create a chain between 2 programs input-to-output?

I have a console program in Linux that when I execute it, it reads some sensors conditions and writes them in the terminal and user can see. Also have another program that when I run, it asks for sensors value and I must put them by hand.
How can I make a connection between these two programs that number one can pass it's values automatically through number 2 and I shall not write them by hand?
For example:
Program number1:
#include <stdio.h>
int main()
{
int[10] sens_value=get_sensors_value();
for(int i=0; i<10; i++)
std::cout<<sens_value;
return 0;
}
Program number 2:
#include <stdio.h>
int main()
{
int[10] sens_values;
for(int i=0; i<10;i++)
std::cin>>sens_values[i];
...etc
return 0
}
You can make only one program and transform your main method in diferent methods and call them in the same program, but you cant conect programs.

How to avoid zombie processes? and what exactly init process does in this situation?

How to avoid zombie processes? and what exactly init process does in this situation?
I've seen this program,but not able to get it:
How does this program creates a zombie process:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t p = fork();
if (p != 0)
{
waitpid(p, NULL, 0); /* See if the child already had ended. */
sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */
pause(); /* Suspend main task. */
}
else
{
sleep(3); /* Just let the child live for some tme before becoming a zombie. */
}
return 0;
}
A child process turns into a zombie process when it did exit but the parent process did not yet run waitpid, wait or waitid on it. In a normal situation a parent would want to know the exit status on the child process it spawned and therefore woud run waitpid on the pid it got from fork.
What happens in your code above:
the child is spawned and exits (leaves the else clause and returns 0)
the parent runs into the endless pause loop until you press ctrl-c (the sleep and waitpid are superflous)
If you start the program and leave it running (./a.out &) and then run ps -fx then you see something like this:
6940 pts/1 SN 0:00 ./a.out
6943 pts/1 ZN 0:00 \_ [a.out] <defunct>
Now, if you kill the parent process (kill 6940) then the child becomes an orphan and the init process automatically becomes the new parent. Since the init process runs waitpid (aka "reaps" the child) on all processes it inherits the zombie process finally is deleted from the process table and does not show up any more via ps -f

Why is the last line not executed by this code?

int main()
{
alarm(2);
printf("still going\n");
while (1);
printf("should this line be executed?\n");
}
I understand that alarm() will interrupt the execution, set the alarm to go off and hand it back. Why does the last line not get executed?
It's not printed because while(1); is an infinite loop. So, in the absence of the alarm() call, that would run forever.
However, the signal generated two seconds after you call alarm() will cause the program to terminate if you're not catching it.
What it won't do is cause just the loop to exit and the program to carry on. It will shut the program down, quick smart.
If you do catch the signal but your catching function just returns, it will end up back inside the infinite loop.
For more detail on those two cases, examine the following code:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int fired = 0;
void handler (int sig) {
fired = 1;
}
int main (void) {
// signal (SIGALRM, handler);
alarm (2);
printf ("Starting.\n");
while (1) {
if (fired) {
fired = 0;
printf ("Alarm fired.\n");
alarm (2);
}
}
printf ("You will never see this.\n");
return 0;
}
If you run that code, it will print out the Starting message, run for about two seconds, then exit without printing anything else. That's because you're not catching the signal so the default action is to just terminate the process.
If you uncomment the call to signal() (disregard for now that it's considered preferable to use sigaction() instead), you'll see the Starting message, followed by a Alarm fired message about every two seconds.
That's because you are catching the signal but, on exit, it returns to inside the infinite loop.
while (1);
This is an infinite loop. Execution will never go beyond this.