CSC 271 - Software I: Utilities and Internals: Lecture 11: Processes and Programming
CSC 271 - Software I: Utilities and Internals: Lecture 11: Processes and Programming
CSC 271 - Software I: Utilities and Internals: Lecture 11: Processes and Programming
and Internals
Lecture 11 : Processes and
Programming
printpid.c
int main(void)
{
printf("The process ID is %d\n",
(int)getpid());
printf("The parent process ID is %d\n",
(int) getppid());
return(0);
}
SIEGFRIE@panther:~/c$
SIEGFRIE@panther:~/c$ printpid
The process ID is 12301
The parent process ID is 12226
SIEGFRIE@panther:~/c$ printpid
The process ID is 12302
The parent process ID is 12226
SIEGFRIE@panther:~/c$ printpid
The process ID is 12303
The parent process ID is 12226
SIEGFRIE@panther:~/c$
ps
ps More Example
SIEGFRIE@panther:~/c$ ps -f
UID PID PPID C STIME TTY TIME CMD
SIEGFRIE 12226 12225 0 22:00 pts/7 00:00:00 -bash
SIEGFRIE 12457 12226 0 22:19 pts/7 00:00:00 ps -f
SIEGFRIE@panther:~/c$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY
TIME CMD
0 S 16131 12226 12225 0 80 0 - 3713 wait pts/7
00:00:00 bash
0 R 16131 12458 12226 0 80 0 - 2112 - pts/7
00:00:00 ps
SIEGFRIE@panther:~/c$ ps -j
PID PGID SID TTY TIME CMD
12226 12226 12226 pts/7 00:00:00 bash
12461 12461 12226 pts/7 00:00:00 ps
SIEGFRIE@panther:~/c$
ps Another Example
SIEGFRIE@panther:~/c$ ps -eo pid -eo ppid
PID PPID
1 0
2 0
3 2
. .
30238 30228
30239 30238
30771 1
31095 1
31174 1
31178 1
SIEGFRIE@panther:~/c$
ps Another Example
SIEGFRIE@panther:~/c$ system
total 268
-rw------- 1 root root 126976 Aug 15 09:50
aquota.user
drwxr-xr-x 2 root root 4096 Nov 6 09:46 bin
drwxr-xr-x 3 root root 4096 Nov 1 15:35 boot
drwxr-xr-x 16 root root 4260 Oct 1 09:02 dev
drwxr-xr-x 145 root root 12288 Nov 7 15:39 etc
drwxr-xr-x 2 root root 4096 Nov 1 15:33 lib64
drwx------ 2 root root 16384 May 21 2011
lost+found
drwxr-xr-x 3 root root 4096 May 21 2011 media
drwxr-xr-x 2 root root 4096
fork and exec
Killing a Process
A process can be killed by issue the correct
signal.
The kill command sends a process a
SIGTERM signal
Creating Processes
There are two methods for creating a new
process:
Using the system call inefficient and has
security risks
Using fork and exec more complex but
provides better flexibility
system
system provides an easy way to execute a
command from within a program, as if the
command were typed within its shell.
system creates a subprocess that runs the
Bourne shell and then hands the commands
to the subprocess to run it.
If the shell cannot be run, it returns 127. If
its any other abnormal termination , it
returns 0.
fork()
fork.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
pid_t child_pid;
child_pid = fork();
if (child_pid != 0) {
printf("This is the parent process, "
"with id %d\n", (int) getpid());
printf("The child\'s process ID is %d\n",
(int) child_pid);
}
else
printf("This is the child process, "
"with id %d\n", (int)getpid());
return(0);
}
Running fork.c
SIEGFRIE@panther:~/c$ gcc -o ../bin/myfork fork.c
SIEGFRIE@panther:~/c$ myfork
The main program process ID is 5169
This is the parent process, with id 5169
The child's process ID is 5170
This is the child process, with id 5170
SIEGFRIE@panther:~/c$
execv()
execv() is one of a family of system calls that
replaces the image of the process running with that
of another process that is specified.
The form of the system call is
int execv(const char *path,
char *const argv[]);
where path is the path of the process to replace
the current one and argv are the command line
parameters, with a NULL at the end.
runhello.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
char *temp[] = {NULL,"hello","world",NULL};
temp[0]="hello";
execv("hello",temp);
printf("error");
}
Running runhello
SIEGFRIE@panther:~/c$ runhello
Filename: hello
hello world
SIEGFRIE@panther:~/c$
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(void)
{
pid_t child_pid;
char *temp[] = {NULL,"hello","world", NULL};
if (child_pid != 0) {
/* This is the parent process. */
printf("This is the parent\n");
exit(0);
}
else {
temp[0]="hello";
execv("hello",temp);
printf("error");
}
}
SIEGFRIE@panther:~/c$ gcc -o ../bin/copyhello
copyhello.c
SIEGFRIE@panther:~/c$ copyhello
This is the parent
SIEGFRIE@panther:~/c$ Filename: hello
hello world
SIEGFRIE@panther:~/c$
Running copyhello
SIEGFRIE@panther:~/c$ copyhello
This is the parent
SIEGFRIE@panther:~/c$ Filename: hello
hello world
SIEGFRIE@panther:~/c$
Using wait()
It is often desirable for the parent process to
wait until one or more child processes have
completed before continuing execution.
This can be done with the wait family of
system calls; they allow you to wait for a
process to finish executing, and enable the
parent process to retrieve information about
its childs termination.
few.c
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
pid_t child_pid;
int status;
int local = 0;
/* now create new process */
child_pid = fork();
if (child_pid >= 0) {
/* fork succeeded */
if (child_pid == 0) {
/* fork() returns 0 for
the child process */
printf("child process!\n");
Process Scheduling
Linux schedules parent and child processes
independent of each other, so there is no
guarantee of which process will run first or
how long it will run before it is pre-empted
for the other process (or some other
process).
The user can specify which process is less
important by assigning it a niceness value,
that can be changed subsequently if the user
desires.
nice An Example
You can run
sort input.txt >output.txt
By writing
nice n 10 input.txt > output.txt
you reduce its priority.
You can use renice to change its nice factor.
Only root can run a process with a negative nice
factor or change it for a process that is running.
Examples of Signals
Type of Signal Explanationn
SIGHUP Linux sends a process this signal when it becomes
disconnected from a terminal
SIGINT Linux sends a process this signal when the user tries to
end it by pressing Ctrl+C.
SIGILL A process gets this signal when it attempts to execute an
illegal instruction.
SIGABRT The abort function causes the process to receive this
signal.
SIGFPE The process has executed an invalid floating-point math
instruction.
SIGKILL This signal ends a process immediately and cannot be
handled.
What Do Processes Do With Signals?
memset()
void *memset(void *str, int c, size_t
n) copies the character c (an unsigned char) to the
first n characters of the string pointed to by the
argument str.
sa_handler()
siguser.c
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
sig_atomic_t sigusr1_count = 0;
SIEGFRIE@panther:~/c$ siguser
Hi there!
Hi there!
Hi there!
^CHi there!
Hi there!
Hi there!
Hi there!
^CHi there!
^CHi there!
Hi there!
SIGILL was raised 3 times
SIEGFRIE@panther:~/c$
Killing a Process
The kill command is used to pass a signal to
a process.
The format of the command:
kill n pid
where n is the signal and pid is the process
id number.
Example
kill -9 20401
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: