Download presentation
Presentation is loading. Please wait.
1
Processes A process is a program in execution A process has (among other things) a number (pid) and a state. The pid enables the OS to distinguish between processes A process is a heavyweight process. A thread is a lightweight process.
2
Variable Types By Storage Class: Static – Once allocated, static variables persist throughout execution of the process. They are defined as: – external variable names, –outside any function, or –defined inside a function with a static qualifier Automatic – Automatic variables come into existence when the block or function they are defined in begins execution and they cease to exist when the block or function exits. They are: – local variable names or –parameters in a function that are not defined with a static qualifier.
3
Variable Types By linkage class: Internal – Not visible to other files that are linked together. Variable names defined inside a function or outside a function with the static qualifier. External – Visible to other files that are linked together. Variable names defined outside a function and with no static qualifier.
4
Static Qualifier ObjectWhere Declared?Static ModifiesStatic Applied? Storage Class Linkage Class variable function inside a function outside any function storage class linkage class yes no yes no yes no static automatic static internal external internal external
5
Program Layout Command Line Arguments and Environment Variables Stack Heap Un-initialized static data Initialized static data Program text argc, argv, environment Activation records for function calls (return address, parameters, saved registers, automatic variables) allocations from malloc family
6
Static Variables If not explicitly initialized, they are initialized to 0 at runtime. Initialized and un-initialized occupy different sections of the program image. Initialized static variables are part of the executable module on disk, whereas un- initialized static variables are not.
7
Static Variable Example Version 1: int myarray[5000] = {1,2,3,4}; void main(int argc, char *argv[]) { myarray[0] = 3; } Version 2: int myarray[5000]; void main(int argc, char *argv[]) { myarray[0] = 3; Do an ls –l after compiling both versions. If integer is 4 bytes, version 1 executable is roughly 20,000 bytes larger.
8
Static Variables and Thread Safe Static variables can make a program unsafe for threaded execution. Readdir uses a static variable to hold return values. This strategy is also used for client/server stubs when marshaling/un-marshaling arguments for remote procedure calls. Therefore, avoid static variables in a threaded environment wherever possible.
9
Show History – list.h /* Program 2.1 */ /* list.h file */ #include #include typedef struct data_struct { time_t time; char *string; } data_t; int add_data(data_t data); data_t *get_data(void); int rewind_list(void);
10
listlib.c declarations /* Program 2.2 */ #include #include #include "list.h" typedef struct list_struct { data_t item; struct list_struct *next; } list_t; static list_t *head_ptr = NULL; static list_t *tail_ptr = NULL; static list_t **trav_ptr = &head_ptr; static data_t temp;
11
listlib.c – add_data /* Allocate a node to hold data and add to end of list. Return 0 if successful or -1 if unsuccessful. */ int add_data(data_t data) { list_t *newnode; if ((newnode = (list_t *)(malloc(sizeof(list_t) + strlen(data.string) + 1))) == NULL) return -1; newnode->item.time = data.time; newnode->item.string = (char *)(newnode + sizeof(list_t)); strcpy(newnode->item.string, data.string); newnode->next = NULL; if (head_ptr == NULL) head_ptr = newnode; else tail_ptr->next = newnode; tail_ptr = newnode; return 0; }
12
listlib.c – get_data /* Return a pointer in temp that has a copy of the data contained in the current node *trav_ptr. If at the end of the list return NULL. In any case, update trav_ptr. */ data_t *get_data(void) { list_t *t; t = *trav_ptr; if (t == NULL) return NULL; if (temp.string != NULL) free (temp.string); if ( (temp.string = (char *) malloc(strlen(t->item.string) + 1)) == NULL) return NULL; temp.time = t->item.time; strcpy(temp.string, t->item.string); trav_ptr = &(t->next); return &temp; }
13
listlib.c – rewind_list /* Set trav_ptr to contain the address of head_ptr. If head_ptr is NULL, return -1 indicating an empty list. Otherwise return 0. */ int rewind_list(void) { trav_ptr = &head_ptr; if (head_ptr == NULL) return -1; else return 0; }
14
keeploglib.c /* Program 2.4 */ #include #include #include "list.h" /* Execute cmd and store cmd and time of execution in history list. */ int runproc(char *cmd) { data_t execute; time(&(execute.time)); execute.string = cmd; if (system(cmd) == -1) return -1; return add_data(execute); } /* Output the history list of the file f */ void showhistory(FILE *f) { data_t *infop; rewind_list(); while ((infop = get_data()) != NULL) fprintf(f, "Command: %s\nTime: %s\n", infop->string, ctime(&(infop->time))); return; }
15
keeplog.c /* Program 2.3 */ #include #include #include #include #ifndef MAX_CANON #define MAX_CANON 8192 #endif void showhistory(FILE *f); int runproc(char *cmd); void main(int argc, char *argv[]) { char cmd[MAX_CANON]; int history = 1; if (argc == 1) history = 0; else if ((argc > 2) || strcmp(argv[1], "history")) { fprintf(stderr, "Usage: %s [history]\n", argv[0]); exit(1); } while(fgets(cmd, MAX_CANON, stdin) != NULL) { if (*(cmd + strlen(cmd) - 1) == '\n') *(cmd + strlen(cmd) - 1) = 0; if (history && !strcmp(cmd, "history")) showhistory(stdout); else if (runproc(cmd)) break; } printf("\n\n>>>>>>The list of commands executed is:\n"); showhistory(stdout); exit(0); }
16
Process ID (pid) Parent Process Child Process getpid(void) – returns the pid of the currently running process. getppid(void) – returns the pid of the parent of the currently running process.
17
User ID (uid) Each process is identified with a particular user called the owner. Each user has a unique ID (uid). getuid(void) – returns the process uid. geteuid(void) – returns the process Effective User ID (euid).
18
euid Each process has an Effective User ID (euid) that determines the privileges a process has for accessing resources such as files. The euid can change during execution.
19
Process/User ID Example /* Example 2.1 */ #include #include #include void main(void) { printf("Process ID: %ld\n", (long)getpid()); printf("Parent process ID: %ld\n", (long)getppid()); printf("Owner user ID: %ld\n", (long)getuid()); printf("Owner euser ID: %ld\n", (long)geteuid()); }
20
Process States new blocked readydone running
21
ps Displays information about processes. Posix.2 Spec 1170
22
ps -l headerMeaning F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME COMMAND Flags associated with the process The process state The user ID of the process owner The process ID The parent process ID The processor utilization used for scheduling The priority of the process The nice value The memory address of the process The size of the process image The address of the event if the process is sleeping The controlling terminal Cumulative execution time Command name
23
fork(void) system call #include pid_t fork(void) _____________________________________ Creates child process by copying parent’s memory image
24
fork return values Returns 0 to child Returns child PID to parent Returns –1 on error
25
Fork Attributes Child inherits: Parent’s memory image Most of the parent’s attributes including environment and privilege. Some of parent’s resources such as open files. Child does not inherit: Parent pid. Parent time clock (child clock is set to 0).
26
fork Example #include #include #include void main(void) { pid_t childpid; if ((childpid = fork()) == 0) { fprintf(stderr, "I am the child, ID = %ld\n", (long)getpid()); /* child code goes here */ } else if (childpid > 0) { fprintf(stderr, "I am the parent, ID = %ld\n", (long)getpid()); /* parent code goes here */ } }
27
fork (Chain) #include #include #include void main(void) { int i; int n; pid_t childpid; n = 4; for (i = 1; i < n; ++i) if (childpid = fork()) break; fprintf(stderr,"This is process %ld with parent %ld\n", (long)getpid(), (long)getppid()); sleep(1); }
28
fork (Fan) #include #include #include void main(void) { int i; int n; pid_t childpid; n = 4; for (i = 1; i < n; ++i) if ((childpid = fork()) <= 0) break; fprintf(stderr, "This is process %ld with parent %ld\n", (long)getpid(), (long)getppid()); sleep(1); }
29
fork (Tree) #include #include #include void main(void) { int i; int n; pid_t childpid; for (i = 1; i < n; ++i) if ((childpid = fork()) == -1) break; fprintf(stderr, "This is process %ld with parent %ld\n", (long)getpid(), (long)getppid()); sleep(1); }
30
pid_t wait(int *stat_loc) Causes caller to pause until a child terminates, or stops until the caller receives a signal. If wait returns because a child terminates, the return value (of type pid_t) is positive and is the pid of that child. Otherwise wait returns –1 and sets errno. stat_loc is a pointer to an integer variable. If caller passes something other than NULL, wait stores the return status (terminate status?) of the child. POSIX specifies the following macros for testing the return status: WIFEXITED, WEXITSTUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, and WSTOPSIG. Child returns status by calling exit, _exit, or return.
31
errno for wait ECHILD indicates there are no unwaited for child processes. EINTR indicates that the call was interrupted by a signal.
32
wait (Race Conditions) /* Program 2.5 */ #include #include #include #include void main (void) { pid_t childpid; int status; if ((childpid = fork()) == -1) { perror("The fork failed"); exit(1); } else if (childpid == 0) fprintf(stderr, "I am the child with pid = %ld\n", (long)getpid()); else if (wait(&status) != childpid) fprintf(stderr, "A signal must have interrupted the wait\n"); else fprintf(stderr, "I am the parent with pid = %ld and child pid = %ld\n", (long)getpid(), (long)childpid); exit(0); }
33
Wait for Child or Error #include #include #include #include #include void main(void) { int status; pid_t childpid; pid_t waitreturn; childpid = fork(); if (childpid == 0) { fprintf(stderr,"Child %ld will sleep for 5 seconds\n",(long)getpid()); sleep(5); fprintf(stderr,"Child %ld will now exit\n",(long)getpid()); exit(0); } fprintf(stderr,"Parent %ld will wait for child %ld\n", (long)getpid(),(long)childpid); while(childpid != (waitreturn = wait(&status))) if ((waitreturn == -1) && (errno != EINTR)) break; }
34
waitpid – WNOHANG # include #include #include #include #include void main(void) { int status; pid_t childpid; pid_t waitreturnpid; childpid = fork(); if (childpid == 0) { fprintf(stderr,"Child %ld will sleep for 5 seconds\n",(long)getpid()); sleep(5); fprintf(stderr,"Child %ld will now exit\n",(long)getpid()); exit(0); } sleep(8); fprintf(stderr,"Parent %ld will wait for any child\n",(long)getpid()); while(waitreturnpid = waitpid(-1, &status, WNOHANG)) if (!((waitreturnpid == -1) && (errno != EINTR))) break; fprintf(stderr,"Parent will exit after receiving %ld from waitpid\n", waitreturnpid); }
35
Fan with wait #include #include #include #include #include void main(void) { int i; int n; pid_t childpid; int status; n = 4; for (i = 1; i < n; ++i) if ((childpid = fork()) <= 0) break; for( ; ; ) { childpid = wait(&status); if ((childpid == -1) && (errno != EINTR)) break; } fprintf(stderr, "I am process %ld, my parent is %ld\n", (long)getpid(), (long)getppid()); }
36
Chain with wait #include #include #include #include #include void main(void) { int i; int n; pid_t childpid; int status; pid_t waitreturn; n = 4; for (i = 1; i < n; ++i) if (childpid = fork()) break; while(childpid != (waitreturn = wait(&status))) if ((waitreturn == -1) && (errno != EINTR)) break; fprintf(stderr, "I am process %ld, my parent is %ld\n", (long)getpid(), (long)getppid()); }
37
Background Processes Child process becomes background process when it executes setsid(). Child that becomes background process never returns to parent. Background processes cannot be interrupted with ctrl-c.
38
execl, execlp, execle “l” – Passes command directly as a parameter in exec. execl searches for command in fully qualified pathname passed as exec parameter or in current directory execlp uses PATH environment variable to find command execle uses environment passed as exec parameter to find command
39
execv, execvp,execve “v” – Passes command as member of argument array (i.e., argv[] or makeargv[]) execv searches for arg array command in fully qualified pathname passed in exec or in current directory execvp uses PATH environment variable to find arg array command execve uses environment passed as exec parameter to find arg array command
40
execl Example /* Program 2.6 */ #include #include #include #include #include void main(void) { pid_t childpid; int status; if ((childpid = fork()) == -1) { perror("Error in the fork"); exit(1); } else if (childpid == 0) { /* child code */ if (execl("/usr/bin/ls", "ls", "-l", NULL) < 0) { perror("Exec of ls failed"); exit(1); } } else if (childpid != wait(&status)) /* parent code */ perror("A signal occurred before the child exited"); exit(0); }
41
execvp Example /* Program 2.7 */ #include #include #include #include #include void main(int argc, char *argv[]) { pid_t childpid, waitreturn; int status; if ((childpid = fork()) == -1) { perror("The fork failed"); exit(1); } else if (childpid == 0) { /* child code */ if (execvp(argv[1], &argv[1]) < 0) { perror("The exec of command failed"); exit(1); } } else /* parent code */ while(childpid != (waitreturn = wait(&status))) if ((waitreturn == -1) && (errno != EINTR)) break; exit(0); }
42
Use of makeargv #include #include #include #include #include #include int makeargv(char *s, char *delimiters, char ***argvp); void main(int argc, char *argv[]) { char **myargv; char delim[] = " \t"; pid_t childpid, waitreturn; int status; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); exit(1); } if ((childpid = fork()) == -1) { perror("The fork failed"); exit(1); } else if (childpid == 0) { /* child code */ if (makeargv(argv[1], delim, &myargv) < 0) { fprintf(stderr, "Argument array could not be constructed\n"); exit(1); } else if (execvp(myargv[0], &myargv[0]) < 0) { perror("The exec of command failed"); exit(1); } } else /* parent code */ while(childpid != (waitreturn = wait(&status))) if ((waitreturn == -1) && (errno != EINTR)) break; exit(0); }
43
Attributes Preserved by Calls to exec AttributeRelevant System Call Process ID Parent process ID Process group ID Session membership Real user ID Real group ID Supplementary group IDs Time left on alarm signal Current working directory Root directory File mode creation mask Process signal mask Pending signals Time elapsed getpid() getppid() getpgid() getsid() getuid() getgid() getgroups() alarm() getcwd() unmask() sigprocmask() sigpending() times()
44
Daemon A background process that runs indefinitely. Examples: Solaris 2 pageout daemon Mailer daemon
45
Background Processes /* Program 2.9 */ #include #include #include #include #include int makeargv(char *s, char *delimiters, char ***argvp); void main(int argc, char *argv[]) { char **myargv; char delim[] = " \t"; pid_t childpid; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); exit(1); } if ((childpid = fork()) == -1) { perror("The fork failed"); exit(1); } else if (childpid == 0) { /* child becomes a background process */ if (setsid() == -1) perror("Could not become a session leader"); else if (makeargv(argv[1], delim, &myargv) < 0) fprintf(stderr, "Argument array could not be constructed\n"); else if (execvp(myargv[0], &myargv[0]) < 0) perror("The exec of command failed"); exit(1); } /* child should never return */ exit(0); } /* parent exits */
46
Biff Biff’s inventor had a dog that barked at mail carriers. Sends a ctrl-g (ASCII 7) to standard error. If there is mail: –The open succeeds. –Printing ASCII 7 causes a beep. Biff
47
Environment List Array of pointers to strings of the form name = value. Name specifies an environment variable Value specifies a string of values.
48
Environment Variables VariableMeaning HOME LANG LC_ALL LC-COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME LOGNAME PATH TERM TZ User’s initial working directory Locale when not specified by LC_ALL or LC_* Overriding name of locale Name of locale for collating information Name of locale for character classification Name of locale for monetary editing Name of locale for numeric editing Name of locale for date/time information Login name associated with a process Path prefixes for finding the executable Terminal type for output Time zone information
49
Environment Variables (cont) In execl, execlp, execv, execvp child inherits environment parent has just prior to execution of exec. In execle and execve, child sets its own environment.
50
Environment Variables (cont) environ getenv env
51
Process Termination Normal or abnormal. Cancel pending timers and signals Release virtual memory resources Release other process-held system resources such as locks Close open files
52
Zombies If a parent process is not waiting for a child when it finishes, the child cannot be terminated by its parent. We call these child processes zombies. Orphaned child processes become zombies when they terminate. System init process (process whose ID is 1) gets rid of orphaned zombies.
53
Normal Termination Return from main. Call to C function exit Call to _exit system call. (note that C function exit calls user-defined exit handlers that usually provides extra cleanup before calling on _exit).
54
exit and _exit Take an integer parameter status that indicates the status of the program. 0 normal termination. Programmer defined non-zero indicates error. At exit C function installs user-defined exit handler. Last-installed, first executed.
55
Abnormal Termination Call abort. Process a signal that causes termination.
56
Critical Sections Interleaved printing. Multi-process to shared memory where at least one process is writing.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.