SYSTEMS PROGRAMMING
LECTURE 4
PROCESSES
A UNIX PROCESS
• Each process is identified by a unique integer,
the process identifier (PID)
• Each identifier is associated with a process
descriptor inside the OS scheduler
• A list of PIDs can be obtained with the ps
aux command
• Information about each process can be found in
/proc/pidn which is a directory
corresponding to each PID
PROCESS STARTUP AND TERMINATION
PROCESS STARTUP AND TERMINATION
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]);
void exit(int status);
void _exit(int status);
• main() is passed the command line arguments and
should return the termination status
• exit() takes the termination status and causes any
files to be properly closed and memory released
• _exit() terminates the process immediately
closing all file descriptors but not cleanly
PROCESS STARTUP AND TERMINATION
#include <stdlib.h>
int atexit(void (*func)(void));
Returns 0 if OK, -1 on error
• The exit() function calls any registered user exit
functions before calling the termination functions
• Exit functions are registered using atexit() which
takes a pointer to a function that does not return
anything and takes no arguments
• Calling _exit() directly allows us to skip these
registered atexit functions
PROCESS STARTUP AND TERMINATION
ENVIRONMENT LIST
• Each program is passed an environment list
• The address of the array of pointers is
contained in the global variable environ:
extern char **environ;
C PROGRAM MEMORY LAYOUT
C PROGRAM MEMORY LAYOUT
• Text segment contains the machine instruction
that the CPU executes (shareable, read-only)
• Initialised data segment contains variables that
are specifically initialised in the program
• Uninitialized data segment (bss) which is
initialised by the kernel to arithmetic 0 or null
pointers before program execution
• Stack, where automatic variables and function
information are stored
• Heap for dynamic memory allocation
SHARED LIBRARIES
• Remove common library routines from the
executable file, maintaining a single copy
somewhere in memory
• Reduces the size of each executable, but adds
runtime overhead
• Library function can be replaced with new
versions without having to edit every program
which use them
• -static to gcc disables use of shared
memory
RESOURCE LIMITS
Every process has a set of resource limits, some
of which can be queried/changed by
#include <sys/resources.h>
int getrlimit(int resource, struct rlimit
*rlptr)
int setrlimit(int resource, const struct
rlimit rlptr);
Both return 0 if OK, nonzero on error
RESOURCE LIMITS
• A process can change its soft limit to a value
less than or equal to its hard limit
• A process can lower its hard limit to a value
greater then or equal to its soft limit
• Only a superuser process can raise hard limits
• Resource limits affect the calling process and
are inherited by its children
• Limits include process available memory, open
files, max CPU time, max number of locks…
PROCESS IDENTIFIERS
• Every process has a unique ID
• PIDs are reused (delay reuse)
• PID 0 is usually the scheduler process
(swapper), and is part of the kernel
• PID 1 is usually init and is invoked by the
kernel at the end of the bootstrap procedure
• It is responsible for bringing up a UNIX system,
bootstrapping the kernel and running read
system-dependent initialisation files
(/etc/rc*)
FORK
• An existing process can create a new one by
calling the fork function
• The new process is called the child process
• Function returns twice, once in the child and
once in the parent process
#include <unistd.h>
pid_t fork(void);
Returns 0 in child, child ID in
parent and 1 on error
FORK
• Both processes continue executing with the instruction
that follows the fork
• The child is a copy of the parent (child gets a copy of
data space, heap and stack)
• Parent and child do not share portions of memory,
however they do share text segment
• Copy-on-write (COW) is generally used, where
regions are shared and have their protections
changed by the kernel to read-only. If either process
tries to modify them, the kernel makes a copy of that
place of memory only (typically page in a virtual
memory system)
FORK
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
{
fprintf(stderr, "fork error");
}
else if (pid == 0)
{
// Child process
} else
{
// Parent process
}
exit(0);
}
FORK USES
• Two main reasons:
• When a process wants to duplicate itself so
that the parent and child can execute
different sections of code at the same time
(common for network servers)
• When a process wants to execute a different
program (common for shells)
FILE SHARING
• All file descriptors that are open in the parent
are duplicated in the child (dup)
• The parent and child share a file table entry
for every open descriptor, sharing the same
offset
• Two cases for handling descriptors after fork:
• Parent waits for child process to complete
• Both processes go their own way, parent and
child close descriptors they don’t need. This is
usually the case for network servers
FILE SHARING
SHARED PROPERTIES
• Real, effective, supplementary IDs
• Process group ID
• Controlling terminal
• CWD, root directory
• File creation mode mask
• Signal mask and dispositions
• Environment
• Attached shared memory segments
• Memory mappings
• Resource limits
VFORK
• vfork is intended to create a new process when
the purpose of the new process is to exec a new
program
• Creates a new process like fork without copying
the address space of the parent into the child
• The child runs in the address space of the parent
• This optimisation provides an efficient gain on
some paged virtual-memory implementations
• Guarantees that the child runs first until it calls
exec or exit
EXIT FUNCTIONS
• A process can terminate normally in 5 ways:
• Executing a return from main
• Calling the exit function
• Calling _exit or _Exit
• Executing a return from the start routine of the
last thread in the process
• Calling pthread_exit from the last thread in
the process
• Abnormal termination include calling abort and
reception of certain signals
EXIT FUNCTIONS
• The init process becomes the parent of any
process whose parent terminates (the process is
inherited by init)
• Whenever a process terminates the kernel goes
through all active processes to see whether the
terminating process is the parent of any
process that still exists
• If so, the parent process ID of the surviving
process is changed to 1
WAIT FUNCTIONS
• When a process terminates the kernel notifies
the parent by sending the SIGCHLD signal
• This has to be an asynchronous notification
• Parent can ignore signal or provide a function
to handle it (default is to ignore)
#include <sys/wait>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc,
int options);
Return PID if OK, 1 on error or 0
WAIT FUNCTIONS
• A process that calls wait or waitpid can:
• Block if all its children are still running
• Return immediately with the termination
status of a child
• Return immediately with an error if it doesn’t
have any child processes
• If a child already terminated and is a zombie
wait returns immediately with the child’s status
• statloc is a pointer to an integer
WAIT FUNCTIONS
Two additional functions allow the kernel to return a
summary of the resources used by the terminated process
and all its children
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resources.h>
pid_t wait3(int *statloc, int options,
struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int
options, struct rusage *rusage);
Return PID if OK, 1 on error or 0
RACE CONDITIONS
• A race condition occurs when multiple
processes are trying to do something with
shared data and the final outcome depends
on the order in which the processes run
• A process that wants to wait for a child to
terminate must call one of the wait
functions
• To avoid race conditions (and polling)
signalling between multiple processes is
required
EXEC FUNCTIONS
• When exec is called, the process is completely
replaced by the new program and the new
program starts executing its main function
• The PID does not change, because a new
process is not created
• Process text, data, heap and stack segments
are replaced by the new program from disk
• The exec, fork and wait functions are the only
process control primitives, except for additional
built-in functions
EXEC FUNCTIONS
#include <unistd.h>
int execl(const char *pathname, const char* arg0
… /* (char *) 0 */);
int execv(const char *pathname, char *const
argv[]);
int execle(const char *pathname, const char
*arg0, … /*(char *) 0, char envp[] */);
int execve(const char *pathname, char *const
argv[], char *const envp[]);
int execlp(const char *filename, const char
*arg0, … /* (char *)0 */);
int execvp(const char *filename, char *const
argv[]);
Return 1 on error, no return on success
EXEC FUNCTIONS
CHANGING USER/GROUP IDS
EXEC FUNCTIONS
• New program inherits some properties from the
calling process:
• PID and parent PID
• User and group IDs
• Controlling terminal
• CWD, root directory
• File mode creation mask
• File locks
• Process signal mask
• Pending signals
• Resource limits
MISC FUNCTIONS
• system allows the user to execute a command
string from within the program
• getlogin return the user login name
#include <stdlib.h>
#include <unistd.h>
int system(const char* cmdstring)
Return value depends on operation
char *getlogin(void)
Return NULL on error
PROCESS GROUPS
• A collection of one or more processes (usually
associated with the same job) that can receive signals
from the same terminal
• Each group has a unique process group ID
• Each process group can have a leader (Group ID =
process ID)
• Leader can create a process group, create processes
in the group and then terminate
• Group exists as long as at least one process is in the
group (group lifetime)

Systems Programming Assignment Help - Processes

  • 1.
  • 2.
    A UNIX PROCESS •Each process is identified by a unique integer, the process identifier (PID) • Each identifier is associated with a process descriptor inside the OS scheduler • A list of PIDs can be obtained with the ps aux command • Information about each process can be found in /proc/pidn which is a directory corresponding to each PID
  • 3.
  • 4.
    PROCESS STARTUP ANDTERMINATION #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]); void exit(int status); void _exit(int status); • main() is passed the command line arguments and should return the termination status • exit() takes the termination status and causes any files to be properly closed and memory released • _exit() terminates the process immediately closing all file descriptors but not cleanly
  • 5.
    PROCESS STARTUP ANDTERMINATION #include <stdlib.h> int atexit(void (*func)(void)); Returns 0 if OK, -1 on error • The exit() function calls any registered user exit functions before calling the termination functions • Exit functions are registered using atexit() which takes a pointer to a function that does not return anything and takes no arguments • Calling _exit() directly allows us to skip these registered atexit functions
  • 6.
  • 7.
    ENVIRONMENT LIST • Eachprogram is passed an environment list • The address of the array of pointers is contained in the global variable environ: extern char **environ;
  • 8.
  • 9.
    C PROGRAM MEMORYLAYOUT • Text segment contains the machine instruction that the CPU executes (shareable, read-only) • Initialised data segment contains variables that are specifically initialised in the program • Uninitialized data segment (bss) which is initialised by the kernel to arithmetic 0 or null pointers before program execution • Stack, where automatic variables and function information are stored • Heap for dynamic memory allocation
  • 10.
    SHARED LIBRARIES • Removecommon library routines from the executable file, maintaining a single copy somewhere in memory • Reduces the size of each executable, but adds runtime overhead • Library function can be replaced with new versions without having to edit every program which use them • -static to gcc disables use of shared memory
  • 11.
    RESOURCE LIMITS Every processhas a set of resource limits, some of which can be queried/changed by #include <sys/resources.h> int getrlimit(int resource, struct rlimit *rlptr) int setrlimit(int resource, const struct rlimit rlptr); Both return 0 if OK, nonzero on error
  • 12.
    RESOURCE LIMITS • Aprocess can change its soft limit to a value less than or equal to its hard limit • A process can lower its hard limit to a value greater then or equal to its soft limit • Only a superuser process can raise hard limits • Resource limits affect the calling process and are inherited by its children • Limits include process available memory, open files, max CPU time, max number of locks…
  • 13.
    PROCESS IDENTIFIERS • Everyprocess has a unique ID • PIDs are reused (delay reuse) • PID 0 is usually the scheduler process (swapper), and is part of the kernel • PID 1 is usually init and is invoked by the kernel at the end of the bootstrap procedure • It is responsible for bringing up a UNIX system, bootstrapping the kernel and running read system-dependent initialisation files (/etc/rc*)
  • 14.
    FORK • An existingprocess can create a new one by calling the fork function • The new process is called the child process • Function returns twice, once in the child and once in the parent process #include <unistd.h> pid_t fork(void); Returns 0 in child, child ID in parent and 1 on error
  • 15.
    FORK • Both processescontinue executing with the instruction that follows the fork • The child is a copy of the parent (child gets a copy of data space, heap and stack) • Parent and child do not share portions of memory, however they do share text segment • Copy-on-write (COW) is generally used, where regions are shared and have their protections changed by the kernel to read-only. If either process tries to modify them, the kernel makes a copy of that place of memory only (typically page in a virtual memory system)
  • 16.
    FORK int main(void) { pid_t pid; if((pid = fork()) < 0) { fprintf(stderr, "fork error"); } else if (pid == 0) { // Child process } else { // Parent process } exit(0); }
  • 17.
    FORK USES • Twomain reasons: • When a process wants to duplicate itself so that the parent and child can execute different sections of code at the same time (common for network servers) • When a process wants to execute a different program (common for shells)
  • 18.
    FILE SHARING • Allfile descriptors that are open in the parent are duplicated in the child (dup) • The parent and child share a file table entry for every open descriptor, sharing the same offset • Two cases for handling descriptors after fork: • Parent waits for child process to complete • Both processes go their own way, parent and child close descriptors they don’t need. This is usually the case for network servers
  • 19.
  • 20.
    SHARED PROPERTIES • Real,effective, supplementary IDs • Process group ID • Controlling terminal • CWD, root directory • File creation mode mask • Signal mask and dispositions • Environment • Attached shared memory segments • Memory mappings • Resource limits
  • 21.
    VFORK • vfork isintended to create a new process when the purpose of the new process is to exec a new program • Creates a new process like fork without copying the address space of the parent into the child • The child runs in the address space of the parent • This optimisation provides an efficient gain on some paged virtual-memory implementations • Guarantees that the child runs first until it calls exec or exit
  • 22.
    EXIT FUNCTIONS • Aprocess can terminate normally in 5 ways: • Executing a return from main • Calling the exit function • Calling _exit or _Exit • Executing a return from the start routine of the last thread in the process • Calling pthread_exit from the last thread in the process • Abnormal termination include calling abort and reception of certain signals
  • 23.
    EXIT FUNCTIONS • Theinit process becomes the parent of any process whose parent terminates (the process is inherited by init) • Whenever a process terminates the kernel goes through all active processes to see whether the terminating process is the parent of any process that still exists • If so, the parent process ID of the surviving process is changed to 1
  • 24.
    WAIT FUNCTIONS • Whena process terminates the kernel notifies the parent by sending the SIGCHLD signal • This has to be an asynchronous notification • Parent can ignore signal or provide a function to handle it (default is to ignore) #include <sys/wait> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); Return PID if OK, 1 on error or 0
  • 25.
    WAIT FUNCTIONS • Aprocess that calls wait or waitpid can: • Block if all its children are still running • Return immediately with the termination status of a child • Return immediately with an error if it doesn’t have any child processes • If a child already terminated and is a zombie wait returns immediately with the child’s status • statloc is a pointer to an integer
  • 26.
    WAIT FUNCTIONS Two additionalfunctions allow the kernel to return a summary of the resources used by the terminated process and all its children #include <sys/types.h> #include <sys/wait.h> #include <sys/time.h> #include <sys/resources.h> pid_t wait3(int *statloc, int options, struct rusage *rusage); pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage); Return PID if OK, 1 on error or 0
  • 27.
    RACE CONDITIONS • Arace condition occurs when multiple processes are trying to do something with shared data and the final outcome depends on the order in which the processes run • A process that wants to wait for a child to terminate must call one of the wait functions • To avoid race conditions (and polling) signalling between multiple processes is required
  • 28.
    EXEC FUNCTIONS • Whenexec is called, the process is completely replaced by the new program and the new program starts executing its main function • The PID does not change, because a new process is not created • Process text, data, heap and stack segments are replaced by the new program from disk • The exec, fork and wait functions are the only process control primitives, except for additional built-in functions
  • 29.
    EXEC FUNCTIONS #include <unistd.h> intexecl(const char *pathname, const char* arg0 … /* (char *) 0 */); int execv(const char *pathname, char *const argv[]); int execle(const char *pathname, const char *arg0, … /*(char *) 0, char envp[] */); int execve(const char *pathname, char *const argv[], char *const envp[]); int execlp(const char *filename, const char *arg0, … /* (char *)0 */); int execvp(const char *filename, char *const argv[]); Return 1 on error, no return on success
  • 30.
  • 31.
  • 32.
    EXEC FUNCTIONS • Newprogram inherits some properties from the calling process: • PID and parent PID • User and group IDs • Controlling terminal • CWD, root directory • File mode creation mask • File locks • Process signal mask • Pending signals • Resource limits
  • 33.
    MISC FUNCTIONS • systemallows the user to execute a command string from within the program • getlogin return the user login name #include <stdlib.h> #include <unistd.h> int system(const char* cmdstring) Return value depends on operation char *getlogin(void) Return NULL on error
  • 34.
    PROCESS GROUPS • Acollection of one or more processes (usually associated with the same job) that can receive signals from the same terminal • Each group has a unique process group ID • Each process group can have a leader (Group ID = process ID) • Leader can create a process group, create processes in the group and then terminate • Group exists as long as at least one process is in the group (group lifetime)