What is a Process? u A process is an executable “cradle” in which a program may run u This...
-
Upload
susanna-haynes -
Category
Documents
-
view
219 -
download
0
Transcript of What is a Process? u A process is an executable “cradle” in which a program may run u This...
What is a Process?
A process is an executable “cradle” in which a program may run
This “cradle” provides an environment in which the program can run, offering memory resources, access to I/O, and access to kernel services.
In Unix, when a new process is created, a copy of the parent process’ environment variables is provided as a default to the new process
Unix Processes
Every process has the following attributes: a process id (a small integer) a user id (a small integer) a group id (a small integer) a current working directory a chunk of memory that hold name/value pairs as text
strings (the environment variables). a bunch of other things…
Identification (uid, gid)
Each process has an associated real uid, but also an effective uid (euid)
The euid is used in determining the access permissions of a given process
getuid() and geteuid() will return the current real and effective user ids.
Effective uids
A process can change its effective id in two ways by setting the setuid bit on a file in the filesystem
chmod u+s myfile ls –l myfile:
-rwsrwxr-x 1 root root 116432 Oct 10 17:34 myfile
by executing the seteuid(uid_t) function
Creating a Process
To create a new process make a fork() system call.
fork() splits the current process in to 2 processes, one is called the parent and the other is called the child.
Parent and Child Processes
The child process is a copy of the parent process It is running the same program It's program counter is in the same place It has its own process ID
The child process inherits many attributes from the parent, including: current working directory user id group id
Command Line Arguments
It is possible for a program to detect which options were used when it is invoked Like "ls –l" or "cp one.txt ../two.txt"
The text of the command that comes after the command line is composed of command line arguments
Your program can access the arguments with a specially structured main() function
Command Line Arguments
int main(int argc, char** argv){
The shell puts the number of command line tokens in argc; the program name is the first of these
Each command line token is stored in the new process memory the shell creates an array and stores a pointer to each
token in the array argv is a pointer to this array
Command Line Arguments #include <iostream>int main(int argc, char** argv){
cout << endl << "ARG COUNT= " << argc << endl;for (int i = 0; i < argc; i++)
cout << "ARG" << i << ": " << argv[i] << endl;}
argv can be treated as an array of strings Each command line token is stored in the new process memory
the shell creates an array and stores a pointer to each token in the array argv is a pointer to this array
The fork() system call
#include <unistd.h>
pid_t fork(void); //prototype for fork
fork() returns a process id (a small integer) fork() returns twice!
In the parent – fork returns the id of the child process In the child – fork returns a 0
Example
#include <unistd.h>#include <stdio.h>
void main(void) {if (fork()) //0 = false, all else true
printf(“I am the parent\n”);else
printf(“I am the child\n”);printf(“I am the walrus\n”);
}
Bad Example (don’t try this!)#include <unistd.h>#include <stdio.h>
void main(void) { while (!fork()) printf("I am the child %d\n“, getpid());
printf("I am the parent %d\n“, getpid());
}
fork bomb!
Switching Programs
fork() creates a new process This would be almost useless if there was not a
way to switch which program is associated with the new process
The exec() system call is used to load a new program into an existing process
The exec() Functions:Out with the old, in with the new
The exec() functions all replace the current running program in the process with another program
bring up an xterm: exec sleep 5 #what happens?
The exec() Functions:Out with the old, in with the new
There are two families of exec() functions, the “l” family (list), and the “v” family (vector)
Each exec() call can choose different ways of finding the executable and whether the environment is delivered in a list or an array (vector)
The environment, open file handles, etc. are passed into the exec’d program
What is the return value of a successful exec() call?
The exec family
When you call a member of the exec family you give it the pathname of the executable file that you want to run, and its command line arguments
If all goes well, exec will never return!
The process becomes the new program
The execl... functions
int execl(const char * path, const char * arg0, ...); executes the command at path, passing it the environments
arg0 ... argn thus, the execl family breaks down argv into its individual
constituents, and then passes them as a list to the execl? function
int execlp(const char * path, const char * arg0, ...); same as execl, but uses $PATH resolution for locating the
program in path
int execle(const char * path, const char * arg0, ...);
The execv... functions
int execv(const char * path, char *const argv[]); executes the command at path, passing it the
environment contained in argv[] int execvp(const char * path, char *const
argv[]); same as execv, but uses $PATH resolution for
locating the program in path int execve(const char * path, char *const argv[],
char * const envp[]);
Death and Destruction
All processes usually end at some time during runtime (with the exception of init)
Processes may end either by: executing a return from the main function calling the exit(int) function calling the _exit(int) function calling the abort(void) function
When a process exits, the OS delivers a termination status to the parent process of the recently deceased process
Waiting
Parent processes often wait for their child processes to end
Parent processes do that via a wait() call pid_t wait(int * status); pid_t waitpid( pid_t pid,
int * status, int options);
waitpid()
pid_t waitpid(pid_t pid, int * status, int options);
pid can be any of 4 values:< -1: wait for any child whose pgid is the
same as pid== -1: waits for any child to terminate== 0: waits for a child in the same process
group as the current process 0: waits for process pid to exit
Problem Children:Orphans and Zombies
If a child process exits before it’s parent has called wait(), it would be inefficient to keep the entire child process around, since all the parent is going to want to know about is the exit status: A zombie is an exited child process that holds nothing
but the child’s exit status If a parent dies before it’s child, the child becomes an
orphan An orphan is “adopted” by the init process (pid == 1),
who will call wait() on behalf of the desceased parent when the child dies