Operating Systems 2017F Lecture 3: Difference between revisions

From Soma-notes
No edit summary
Ssarazin (talk | contribs)
Line 15: Line 15:
==== What is fork? ====
==== What is fork? ====
* Fork creates a new program but contains the same code (call the clone system call) and only argv[] and envp[] passed on to the new born program
* Fork creates a new program but contains the same code (call the clone system call) and only argv[] and envp[] passed on to the new born program
- More on creating a process using fork().
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char* argv[], char* envp[]) {
  int child;
  int status;
  pid_t retval;
       
  child = fork();
  printf("Hello!  I am %d, my parent is %d.\n",
          getpid(), getppid());
  if (child == 0) {
  /* We're the child */
    sleep(3);
    printf("Child all done!\n");
  } else {
  /* We're the parent */
    retval = wait(&status);
    printf("Parent all done!  Child %d returned %d.\n",
            (int) retval, WEXITSTATUS(status));
  }
       
  return 42;
}
- sleep(int)
  - causes the current process to do nothing for the specified number of seconds.
- pid_t = fork(void)
  - fork creates a clone of the parent process
  - pid is 0 when the child process is running and >0 when the parent process is running.  Both processes will return from the system call to fork().
- pid_t = wait(int * status)
  - this system call is equivalent to pid_t = waitpid(-1, &status, 0)
  - the wait system call suspends the current process until one of its children has terminated.
  - pid_t specifies which child to wait for.  Various options are available that define how to wait.
  - int* status holds the status of the wait system call.  There are various macros that define what the status can be.
- '''What happens when the newline character is removed from the printf statement?'''
  - printf holds the output in a buffer until it receives a newline character.  The result is the output does not print when expected.
  - The kernel is doing things as it is told, so the c library is at fault.
  - We could get the expected output if we bypass the c library using a system call: "write"
  - running an "strace" on the executable will show us the order in which the processes were run to help debug the problem.
- '''What happens in the conditional?'''
  - When the parent process calls fork(), a child process is created and begins executing at the fork() statement.  The OS returns a value from fork() which indicates which process is
    currently running.
  - If fork() returns zero then the child sleeps for 3 seconds before printing.  The sleep system call forces the child process to do nothing for 3 seconds.
  - if fork() returns anything else, it is assumed to be the parent process.  In this case the wait() system call is run by the parent which causes the parent process to wait for its child 
    to finish; then the printf executes and prints the child process id and its return value from main.  The macro WEXITSTATUS retrieves 42.


==== What Happen to the child process after the parent process died? ====
==== What Happen to the child process after the parent process died? ====

Revision as of 00:01, 5 October 2017

Video

Video from the lecture given on September 14, 2017 is now available.

Code

Code and files from the lecture (captured as they were at the end) are available here.


Notes

Commands

  • -wall: show all warning
  • less: allow screen navigation, hit q to quit

What is fork?

  • Fork creates a new program but contains the same code (call the clone system call) and only argv[] and envp[] passed on to the new born program
- More on creating a process using fork().
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


int main(int argc, char* argv[], char* envp[]) {
 int child;
 int status;
 pid_t retval;
       
 child = fork();
 printf("Hello!  I am %d, my parent is %d.\n",
         getpid(), getppid());
 if (child == 0) {
 /* We're the child */
   sleep(3);
   printf("Child all done!\n");
 } else {
 /* We're the parent */
   retval = wait(&status);
   printf("Parent all done!  Child %d returned %d.\n",
           (int) retval, WEXITSTATUS(status));
 }
       
 return 42;

}

- sleep(int)
  - causes the current process to do nothing for the specified number of seconds.
- pid_t = fork(void)
  - fork creates a clone of the parent process
  - pid is 0 when the child process is running and >0 when the parent process is running.  Both processes will return from the system call to fork().
- pid_t = wait(int * status)
  - this system call is equivalent to pid_t = waitpid(-1, &status, 0)
  - the wait system call suspends the current process until one of its children has terminated.
  - pid_t specifies which child to wait for.  Various options are available that define how to wait.
  - int* status holds the status of the wait system call.  There are various macros that define what the status can be.
- What happens when the newline character is removed from the printf statement?
  - printf holds the output in a buffer until it receives a newline character.  The result is the output does not print when expected. 
  - The kernel is doing things as it is told, so the c library is at fault.
  - We could get the expected output if we bypass the c library using a system call: "write"
  - running an "strace" on the executable will show us the order in which the processes were run to help debug the problem.
- What happens in the conditional?
  - When the parent process calls fork(), a child process is created and begins executing at the fork() statement.  The OS returns a value from fork() which indicates which process is 
    currently running.
  - If fork() returns zero then the child sleeps for 3 seconds before printing.  The sleep system call forces the child process to do nothing for 3 seconds.
  - if fork() returns anything else, it is assumed to be the parent process.  In this case the wait() system call is run by the parent which causes the parent process to wait for its child   
    to finish; then the printf executes and prints the child process id and its return value from main.  The macro WEXITSTATUS retrieves 42.

What Happen to the child process after the parent process died?

  • Every child process must have a currently running parent. When the parent process die, kernel collect the dead body(return value) and re-parent the process
  • In the demo showed in class, “system d user” became its new parent
    • Use command "Pstree" to show process hierarchy

What is zombie process?

  • When a process die it become 'zombie' (s = sleep, z = zombie)
  • We can use wait to be a 'good' parent

How to load a new binary manually

  • Use the execve command.
    • We can fork child process to handle dangerous task (“Suicide Squad”), or handle all incoming request

Manipulating environment variables

  • argc tells the number of argument in command line, while argv[] contains the actual command obtained in the command line