60-256 System Programming: Process Control III
Content
COMP 2560 System Programming:
Process Control III
Courtesy of Dr. B. Boufama
modified by Dan Wu
School of Computer Science University of Windsor
–
Instructor: Dr. Dan Wu
Process Control III
1
Copyright @ 2019, 2020, 2021 all rights reserved
Content
Content
1
Differentiating a process: exec()
2
Changing directories: chdir()
3
System scheduling priority
4
Process groups
Process Control III
2
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
The exec() family of system calls allows a process to replace its current code, data and stack with those of another program.
Synopsis
int execl(const char *pathname, [const char
*argi ,]+ NULL)
int execlp(const char *pathname, [const char *argi ,]+ NULL)
int execv(const char *filename, const char
*argv[])
int execvp(const char *filename, const char
*argv[])
where i = 0, . . . , n and + means one or more times.
The difference between these 4 system calls has to do with syntax.
execl() and execv() require the whole pathname of the executable program to be supplied.
execlp() and execvp() use the variable $PATH to find the program.
Process Control III
3
Copyright @ 2019, 2020, 2021 all rights reserved
Ignore the yellow ones for this course
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Process Control III
4
man exec
Copyright @ 2019, 2020, 2021 all rights reserved
dan wu (dw) –
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
A successful call to exec() never returns.
exec() returns -1 if not successful.
For both execl() and execlp() arg0 must be the name of the program.
For both execv() and execvp() arg[0] must be the name of the program.
Process Control III
5
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example using execl (execl1.c)
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“Before: process id %d\n”,getpid());
if ((pid = fork())==0){
printf(“I am the child %d\n”,getpid()); sleep(5);
printf(“Listing content of current directory…\n”); execl(“/bin/ls”,”ls”,”-l”, “-t”, (char *)0);
}
else{
printf(“I am the parent %d\n”, getpid()); int status;
int term_pid = wait(&status);
printf(“Child %d has listed the content of current directory\n”, term_pid); exit(1);
}
}
Process Control III
6
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example using execlp (execlp1.c)
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“Before: process id %d\n”,getpid());
if ((pid = fork())==0){
printf(“I am the child %d\n”,getpid()); sleep(5);
printf(“Listing content of current directory…\n”); execlp(“ls”,”ls”,”-l”,(char *)0);
}
else{
printf(“I am the parent %d\n”, getpid()); int status;
int term_pid = wait(&status);
printf(“Child %d has listed the content of current directory\n”, term_pid); exit(1);
}
}
Process Control III
7
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example using execv (execv1.c)
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“Before: process id %d\n”,getpid());
if ((pid = fork())==0){
printf(“I am the child %d\n”,getpid()); sleep(5);
printf(“Listing content of current directory…\n”);
char* arg_list[3] = {“ls”, “-l”, (char *)0};
// OR
// char* arg_list[3];
// arg_list[0] = “ls”;
// arg_list[1] = “-l”;
// arg_list[2] = 0;
execv(“/bin/ls”,arg_list);
}
else{
printf(“I am the parent %d\n”, getpid()); int status;
int term_pid = wait(&status);
printf(“Child %d has listed the content of current directory\n”, term_pid); exit(1);
}
}
Process Control III
8
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example using execvp (execvp1.c)
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“Before: process id %d\n”,getpid());
if ((pid = fork())==0){
printf(“I am the child %d\n”,getpid()); sleep(5);
printf(“Listing content of current directory…\n”);
char* arg_list[3] = {“ls”, “-l”, (char *)0};
// OR
// char* arg_list[3];
// arg_list[0] = “ls”;
// arg_list[1] = “-l”;
// arg_list[2] = 0;
execvp(“ls”,arg_list);
}
else{
printf(“I am the parent %d\n”, getpid()); int status;
int term_pid = wait(&status);
printf(“Child %d has listed the content of current directory\n”, term_pid); exit(1);
}
}
Process Control III
9
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Inheriting and changing directory
A child process inherits its current working directory from its parent.
Each process can change its working directory using chdir().
chdir() synopsis:
int chdir(const char * pathName); chdir() returns 0 if successful -1 otherwise.
It fails if the specified path name does not exist or if the process does not have execute permission from the directory.
Process Control III
10
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
System scheduling priority
Every process has a system scheduling priority.
Each process runs at a default system priority: the priority inherited from its parent.
The numerical range of priority values is: -20 to 19 (Only the super-user can get negative values). However, this range differs from one Unix platform to another.
The scheduling priority can be changed using the nice()
system call.
Priority value can also be changed using
setpriority().
Priority value can be obtained using getpriority().
The priority value affects the amount of CPU time allocated to the process. The higher the value, the lower the process’ priority.
Process Control III
11
man 2 nice
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Changing priority nice()
Synopsis:
int nice(int delta);
nice() adds delta to the process current priority value. Note that only super-user processes can have a negative priority value.
nice() returns the new priority value if successful and -1 otherwise.
Process Control III
12
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
getpriority() and setpriority()
getpriority()
Synopsis: int getpriority(int which, id t who); obtains the current scheduling priority of a process, process group, or user. Returns the priority value on success, -1 on failure.
setpriority()
Synopsis: int setpriority(int which, id t who, int priority);
sets the scheduling priority of a process, process group, or user. Returns 0 on success, -1 on failure.
The two functions require
#include
which identifies whether it is a process (PRIO PROCESS), process group…etc.
who interpreted as a process id, group id,…etc. If who is 0, the calling process, (or group,…etc) is considered. priority is the priority value (in the appropriate range).
Process Control III
13
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example… (priority.c)
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“I am the parent %d. My priority is %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
if ((pid = fork())==0){
printf(“I am the child %d. My priority is %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
printf(“Child: nice(19) returns %d\n”,nice(19)); printf(“I am the child %d. My priority is now %d\n”,
getpid(),getpriority(PRIO_PROCESS,getpid())); exit(20);
}
else{
sleep(5);
printf(“Changing parent’s priority…\n”); printf(“Parent: nice(10) returns %d\n”,nice(10)); int status;
int term_pid = wait(&status);
int new_pid = fork(); if (new_pid == 0){
printf(“I am the new child %d. My priority is %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
printf(“New child: nice(5) returns %d\n”,nice(5)); printf(“I am the new child %d. My priority is now %d\n”,
getpid(),getpriority(PRIO_PROCESS,getpid())); exit(21);
}
else term_pid = wait(&status);
}
}
Process Control III
14
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
…
The output of the previous program is:
I am the parent 9306. My priority is 0 I am the child 9307. My priority is 0 Child: nice(19) returns 19
I am the child 9307. My priority is now 19 Changing parent’s priority…
Parent: nice(10) returns 10
I am the new child 9308. My priority is 10 New child: nice(5) returns 15
I am the new child 9308. My priority is now 15
Process Control III
15
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example (priority2.c)…
#include
#include
#include
#include
int main(int argc, char* argv[]) { int pid;
printf(“I am the parent %d. My priority is %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
if ((pid = fork())==0){
printf(“I am the child %d. My priority is %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
setpriority(PRIO_PROCESS,getpid(),19);
printf(“I am the child %d. My priority is now %d\n”, getpid(),getpriority(PRIO_PROCESS,getpid()));
exit(20);
}
else{
sleep(5);
printf(“Changing parent’s priority…\n”); printf(“Parent: nice(10) returns %d\n”,nice(10)); int status;
int term_pid = wait(&status);
}
}
Process Control III
16
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
…
The output of the previous program is:
I am the parent 13557. My priority is 0 I am the child 13558. My priority is 0
I am the child 13558. My priority is now 19 Changing parent’s priority…
Parent: nice(10) returns 10
Process Control III
17
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Process groups (Read Ch. 9, not required for this course)
Every process is a member of a process group. A child inherits its process group from its parent.
When a process execs, its process group remains the same.
A process may change its process group to a new value: either to become a member of another group or to create its own group (in which the process will initially be the leader and sole member).
One of the group members is the group leader. Each member of the group has the group leader’s process-ID as its process-group-ID.
The kernel provides a system call to send a signal to each member of a designated process group.
This would be used to terminate the entire group as a whole, but any signal can be broadcast in this way.
Process Control III
18
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
setpgid()
#include
#include
setpgid()
Synopsis: int setpgid(pid t pid,pid t pgid)
sets the process group ID of the process, whose ID is pid, to pgid. It returns 0 if successful and -1 otherwise.
If pgid is equal to pid, the process becomes a process group leader.
If pid is equal to 0, the calling process group ID is set to
pgid.
if pgid is equal 0, the process specified by pid becomes a process group leader.
Process Control III
19
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
getpgid()
#include
#include
getpgid()
Synopsis: pid t getpgid(pid t pid)
returns the process group ID of the process with PID equal to
pid. If pid is 0, the calling process group ID is returned.
Process Control III
20
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Example (pgid1.c)
#include
#include
#include
#include
int main(int argc, char *argv[]){ int pid = getpid();
printf(“Parent: PID = %d, PPID = %d, PGID = %d\n”,pid,getppid(),getpgid(pid));
if ((pid = fork())==0){
printf(“Child: PID = %d, PPID = %d, PGID = %d\n”, getpid(),getppid(),getpgid(getpid()));
exit(1);
}
sleep(5);
}
Output:
Parent: PID = 20814, PPID = 20381, PGID = 20814 Child: PID = 20815, PPID = 20814, PGID = 20814
Process Control III
21
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Another example (pgid2.c)
#include
#include
#include
#include
int main(int argc, char *argv[]){ int pid = getpid();
printf(“Parent: PID = %d, PPID = %d, PGID = %d\n”,pid,getppid(),getpgid(pid));
if ((pid = fork())==0){
printf(“Child: PID = %d, PPID = %d, PGID = %d\n”,getpid(),getppid(),getpgid(getpid())); setpgid(0,0); //or setpgid(getpid(),0);
printf(“Child after setpgid: PID = %d, PPID = %d, PGID = %d\n”, getpid(),getppid(),getpgid(getpid()));
}
sleep(5);
}
Output:
Parent: PID = 22295, PPID = 20381, PGID = 22295 Child: PID = 22296, PPID = 22295, PGID = 22295
Child after setpgid: PID = 22296, PPID = 22295, PGID = 22296
Process Control III
22
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
A small shell program…
Example
Write a C program, that behaves like a small shell, to process commands entered by the user.
The program should assemble commands and execute them, either in the background or foreground.
The commands/programs location can be anywhere in
$PATH and might have arguments.
Process Control III
23
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
Algorithm
Algorithm:
While(1) begin
get command-line from user assemble command args duplicate current process
child should exec to the new program if (foreground execution) then
parent process waits for its child to terminate
end
Process Control III
24
Copyright @ 2019, 2020, 2021 all rights reserved
Differentiating a process: exec() Changing directories: chdir() System scheduling priority
Process groups
More example code for process control
fork_example.c
Exec-example.c
Execv-example.c
Myecho.c
runls3.c
Docommand.c
Smallsh.h
Proc_line.c (b 18, b41)
Userin.c
Runcommand.c
Main_smallsh.c (b 11, check inpbuf tokbuf)
Process Control III
25
Copyright @ 2019, 2020, 2021 all rights reserved