0% found this document useful (0 votes)
4 views57 pages

10 Systems Programming-Process, Feb 09

The document provides an overview of process management in operating systems, detailing the structure and components of a process, including the Process Control Block (PCB) and the various system calls associated with process management. It explains the stages of the Linux boot process, the creation and termination of processes, and the relationships between parent and child processes. Additionally, it covers concepts like orphan and zombie processes, race conditions, and the exec family of system calls for executing programs.

Uploaded by

Raj Savaliya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views57 pages

10 Systems Programming-Process, Feb 09

The document provides an overview of process management in operating systems, detailing the structure and components of a process, including the Process Control Block (PCB) and the various system calls associated with process management. It explains the stages of the Linux boot process, the creation and termination of processes, and the relationships between parent and child processes. Additionally, it covers concepts like orphan and zombie processes, race conditions, and the exec family of system calls for executing programs.

Uploaded by

Raj Savaliya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

IT628 Systems Programming

Process
Process Management System Call Hierarchy

Process management

nice chdir wait fork exec exit Signals


setgid setpgrp getpgrp getppid setuid

getgid getrgid getuid getruid

alarm signal kill pause


Process Concept
• A process is program in execution.
Multiple instances of same
program are different processes
• Process memory image contains 3
components
• User Address Space
• An executable program code
• Associated data needed by program
• Kernel Address Space
• Execution context needed by OS to
manage the process (Process ID, CPU
registers, CPU time, stack, open files,
memory space for code data and stack,
signals etc)
Process Control Block (PCB)
• For each process PCB is maintained in
system’s process table array or linked list
• PCB is included in context along with
stack
• Typical PCB contains:
• Process ID, Parent Process ID
• Process State
• CPU State: CPU register contents, PSW
(Process Status Word)
• Priority and other Scheduling Info
• Pointers to different memory areas
• Open file information
• Signals and signal handler info
• Various accounting info like CPU time etc
• Many other OS specific fields can be there
e.g. Linux PCB has 100+ fields
Example of process and PCB in memory
Stages of Linux Boot Process
• BIOS: Basic Input/output System performs system integrity checks,
search boot loader on cd-rom, disk and executes MBR boot loader
• MBR: Master Boot Record  available in 1st sector of bootable disk,
executes GRUB boot loader
• GRUB: Grand Unified Bootloader  if multiple kernel images are installed
you can select using GRUB , executes selected Kernel
• Kernel: Kernel  Mounts the root file system, executes Init (init is the first
program to run)
• Init: Init  executes run level programs depending on runlevel (runlevels:
halt, single user, multiuser without NFS, Full multiuser etc)
• Runlevel  Runlevel programs are executed from etc/rc.d/rc*.d
Process Tree on Unix System
• Swapper is scheduler
• Init is the root of all user
processes
• Pagedaemon is responsible for
virtual page management
Operations on Process
• Process Creation
• Data structures like PCB set up and initialized
• Initial resources allocated and initialized if needed
• Process added to ready queue (queue of processes ready to run)
• Process Scheduling
• CPU is allotted to process and process start running
• Process Termination
• Process is removed
• Resources are reclaimed
• Some data may be passed to parent process such as exit status
• Parent process may be informed (e.g. SIGCHLD signal in Unix)
Events Leading to Process Creation
• System boot – During system booting several background processes
or daemons are started
• User Request – When command is executed on CLI shell or double-
click on application
• A process can spawn another i.e. child process using fork() e.g. server
can create new process for each client request or init deaomon waits
for login and spawns new shell
• Batch system takes next job to process
Events Leading to Process Termination
• Process executes last statement and asks operating system to
terminate it using exit() function
• Process encounter fatal error like divide by zero, I/O error, memory
allocation errors etc
• Parent may terminate execution of child process by executing kill
(SIGKILL signal) function for some specific reason
• Task assigned to child is no longer needed
• Child has exceeded the allocated resources
• Parent is exiting
• Some OS may not allow child to continue if parent terminates
Process Relation Between Parent and Child
Processes
• Resource sharing possibilities
• Parent and children share all resources
• Children share subset of parent ’s resources
• Parent and child share no resources
• Execution possibilities
• Parent and children execute concurrently
• Parent waits until children terminate
• Memory address space possibilities
• Address space of child duplicate of parent
• Child has a new program loaded into it
Process Management System Call
System Call Signature Purpose of System Call Return Values
pid_t getpid(void) Get process ID Returns process ID of calling
process
pid_t getppid(void) Get parent’s process ID Returns parent process ID of calling
process
pid_t fork(void) Create child process by duplicating Returns 0 in child, process ID of
memory of parent process. Child child in parent, -1 on error
gets copy of data space etc. Now
uses Copy-On-Write (COW)
Pid_t vfork(void) Now Absolete: Earlier fork() used to Returns 0 in child, process ID of
copy a complete memory of parent child in parent, -1 on error
to child so vfork was used as
optimized method
void exit(int) Terminated the process Parent of process will receive the
success value passed as int
Process Management System Call
System Call Signature Purpose of System Call Return Values
pid-t wait(int *statloc) Wait for a child process to Returns process ID of child that
Terminate terminated and statloc indicates
pid_t wait(pid_t pid, int *statloc..) Wait for child with given pid returned status
int exec???(const chat pathname, Replaces the current process Return -1 on error and no return on
const chat *arg0, …) memory with new process to be success
executed in pathname
fork() and exec() memory changes
Clone the child process Replace child image
pid = fork() exec(prog_name, ) from child
OS OS OS
Empty Space Empty Space Empty Space
P1 Context P1 Context P1 Context
Process P1 Data Parent P1 Data Parent P1 Data
Process Process P1 Code
P1 Code P1 Code

Empty Space Empty Space

Empty Space P1 Context P2 Context


Child P1 Data Child P2 Data
Process Process
P1 Code P2 Code
Process States (6 State Model)
• Process changes state as it executes:
• Idle  process is being create by fork() system call and is not yet runnable
• Runnable  process is waiting for CPU to start running
• Running  process is current running executing instructions
• Sleeping  process is waiting for an event to occur e.g. if process has
executed read() system calls, it will go in sleep until I/O request is complete
• Suspended  process has been “frozen” by signal such as SIGSTOP, it will
resume when SIGCONT signal is received e.g. Ctrl-Z suspend all the processes
of foreground job
• Zombified  process has terminated but has not yet returned its exit code to
its parent. The process remains in zambie state until parent accepts return
code using wait() system call
Process State Transition
System Calls fork(), getpid() and getppid()
example
#include <stdio.h>
main()
{ int pid;
printf(“I’m the original process with PID %d and PPID %d. \n”, getpid(), getppid() );
pid = fork(); /* Duplicate. Child and parent continue from here */
if ( pid!= 0 ) /* pid is non-zero, so I must be the parent */  Parent and Child execute
from this point
{
printf(“I’m the parent process with PID %d and PPID %d. \n”, getpid(), getppid() );
printf(“My child’s PID is %d \n”, pid );
}
System Calls fork(), getpid() and getppid()
example
else /* pid is zero, so I must be the child */
{
printf(“I’m the child process with PID %d and PPID %d. \n”,
getpid(), getppid() );
}
printf(“PID %d terminates. \n”, getpid() ); /* Both processes execute
this */
}
System Calls fork(), getpid() and getppid()
example
$ myfork
I’m the original process with PID 13292 and PPID 13273.
I’m the parent process with PID 13292 and PPID 13273.
My child’s PID is 13293.
I’m the child process with PID 13293 and PPID 13292.
PID 13293 terminates. ---> child terminates.
PID 13292 terminates. ---> parent terminates.
WARNING:
it is dangerous for a parent process to terminate without waiting for the death of
its child.
The only reason our program doesn’t wait for its child to terminate is because we
haven’t yet used the “wait()” system call!.
What happens with this code?
int main(void)
{
fork();
fork();
fork();
}

How many total processes will be created?


Orphan Process
• If parent process does not wait for child and it first terminates leaving child process
orphan
• Orphan processes are adopted by init process which started the parent (i.e. parent of parent)
init

Parent
dies adopt
first child

Child
survives
the parent
Orphan Process Example
else /* pid is zero, so I must be the child $ orphan ---> run the program.
*/ I’m the original process with PID 13364 and
{ PPID 13346.
sleep(10); // add sleep so child process I’m the parent process with PID 13364 and
will terminate later then parent PPID 13346.
printf(“I’m the child process with • PID PID 13364 terminates.
13364 terminates. PID %d and PPID %d. \n”, I’m the child process with PID 13365 and
getpid(), getppid() ); PPID 1. ---> orphaned!
} PID 13365 terminates.
printf(“PID %d terminates. \n”, getpid() ); $
/* Both processes execute this */
}
Note the change in PPID for child processes
System Call wait() to avoid orphans
#include <stdio.h>
main()
{ int pid, status;
printf(“I’m the original process with PID %d and PPID %d. \n”, getpid(), getppid() );
pid = fork(); /* Duplicate. Child and parent continue from here */
if ( pid!= 0 ) /* pid is non-zero, so I must be the parent */
{
printf(“I’m the parent process with PID %d and PPID %d. \n”, getpid(), getppid() );
printf(“My child’s PID is %d \n”, pid );
childPid = wait( &status ); // add wait in parent process to wait for child process, child will not
become orphan
}
else…..
Zombie Process
#include <stdio.h> $ zombie & ---> execute the program in the background using &
main() [1] 13545
{ $ ps ---> obtain process status.
int pid; PID TT STAT TIME COMMAND
pid = fork(); /* Duplicate */ 13535 p2 S 0:00 -ksh (ksh) ---> the shell.
if ( pid!= 0 ) /* Branch based on return value from fork() */ 13545 p2 S 0:00 zombie ---> the parent process.
{ 13546 p2 Z 0:00 <defunct> ---> the zombile child.
while (1) /* Never terminate, and never execute a wait() */ 13547 p2 R 0:00 ps
sleep(1000);
} $ kill 13545 ---> kill the parent process.
else [1] Terminated zombie
{
exit(42); /* Exit with a silly number */ $ ps ---> notice that the zombie is gone now.
} PID TT STAT TIME COMMAND
} 13535 p2 S 0:00 -ksh (ksh)
13547 p2 R 0:00 ps
Race Condition
You can call this as critical section $ test_fork
static void charatatime(char *str) 12345678901234567890
{ abcdefghijklmnopqrstuvwxyz
char *ptr; $ test_fork
int c; 12a3bc4d5e6f78901g23hi4567jk890
setbuf(stdout, NULL); Lmnopqrstuvwxyz
for (ptr=str;c=*ptr++;) putc(c,stdout);
} Need to have parent wait for child or child wait
main() for parent to complete the critical section code.
{
This can be done using signals which will study
in next chapter
pid_t pid;
if ((pid = fork())<0) printf("fork error!\n");
else if (pid ==0) charatatime("12345678901234567890\n");
else charatatime("abcdefghijklmnopqrstuvwxyz\n");
}
Additional Status Info from wait() System Call
childpid = wait(&wstatus);  returns the exit status from child which can further be
inspected using these macros
WIFEXITED(wstatus)  returns true if child terminated normally
WEXITSTATUS(wstatus)  returns exit status (least significant 8 bits)
WIFSIGNALED(wstatus)  returns true if child process was terminated by a signal
WTERMSIG(wstatus)  returns the number of signal
WCOREDUMP(wstatus)  returns true if child produced a core dump
WIFSTOPPED(wstatus)  returns true if child was stopped by a signal
WSTOPSIG(wstatus)  returns the signal number which caused child to stop
WIFCONTINUED(wstatus)  returns true if child was resumed with SIGCONT signal
exec() family of System Calls
When fork() creates a child process with a copy of same code, data etc as parent process
but if you need to run another process as child process then 
A process may replace its current code, data, and stack with those of another executable
by using one of the “exec()” family of system calls
When a process executes an “exec()” system call, its PID and PPID numbers stay the same -
only the code that the process is executing changes.
System Call:
int execl( const char* path, const char* arg0, const char* arg1,…, const char* argn, NULL )
int execv( const char* path, const char* argv[] )
int execlp( const char* path, const char* arg0, const char* arg1, …, const char* argn, NULL)
int execvp( const char* path, const char* argv[] )
The “exec()” family of system calls replaces the calling process’ code, data, and stack with
those of the executable whose pathname is stored in path.
Difference in exec() System Calls
• “execlp()” and “execvp()” use the $ PATH environment variable to find
path.
• If the executable is not found, the system call returns a value of -1; otherwise,
the calling process replaces its code, data, and stack with those of the
executable and starts to execute the new code.
• “execl()” and “execlp()” invoke the executable with the string
arguments pointed to by arg1 through argn.
• arg0 must be the name of the executable file itself, and the list of arguments
must be null terminated.
• “execv()” and “execvp()” invoke the executable with the string
arguments pointed to by argv[1] to argv[n], where argv[n+1] is NULL.
• argv[0] must be the name of the executable file itself.
System Call exec() example
the program displays a small message and then replaces its code with that of the “ls”.
#include <stdio.h>
main()
{
printf(“I’m process %d and I’m about to exec an ls -l \n”, getpid() );
execl( “/bin/ls”, “ls”, “-l”, NULL ); /* Execute ls */
printf(“This line should never be executed \n”);
}
$ myexec ---> run the program.
I’m process 13623 and I’m about to exec an ls -l
total 125
-rw-r--r-- 1 glass 277 Feb 15 00:47 myexec.c
-rwxr-xr-x 1 glass 24576 Feb 15 00:48 myexec
Background Process using fork() and exec()
System Calls
#include <stdio.h> $ ./background ls -R -ltr /usr/ ---> run
int main( int argc, char* argv[] ) the program.
{ Confirm that “ls” command is
showing up in ps listing
if ( fork() == 0 ) /* Child */ faculty@faculty-OptiPlex-3040:~$ ps
{ 2579
execvp( argv[1], &argv[1] ); /* PID TTY STAT TIME COMMAND
Execute other program */ 2579 pts/22 D 0:24 ls -R -ltr /usr/
fprintf( stderr, “Could not execute %s
\n”, argv[1] );
}
}
System Call : system()
int system(const char *command);
• Implemented using fork(), exec() and waitpid()
• Used to execute the command passed as parameter
e.g. system(“ls -ltr”);  runs “ls –ltr” command
system(“date > tempfile”);  create tempfile with output redirected
from date
How to get additional information about
process which is running
• When a process starts it create a directory with process ID under /proc for
per process information
First check the pid using ps command
faculty@faculty-OptiPlex-3040:/proc$ ps –aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

faculty 29593 0.7 3.9 2194648 156540 ? Sl Jan17 20:48
/usr/lib/firefox/firefox -contentproc -chil
….
Process ID for this process is 29593
How to get additional information about process
which is running – Collect System Information
Now change directory to /proc/29593 which is the directory lrwxrwxrwx 1 faculty faculty 0 Jan 19 02:46 cwd ->
for this process. List the content of the that directory /home/faculty
faculty@faculty-OptiPlex-3040:/proc/29593$ ls –l -r-------- 1 faculty faculty 0 Jan 19 11:08 environ
total 0
lrwxrwxrwx 1 faculty faculty 0 Jan 19 02:44 exe ->
/usr/lib/firefox/firefox
dr-xr-xr-x 2 faculty faculty 0 Jan 19 11:17 attr dr-x------ 2 faculty faculty 0 Jan 19 02:46 fd
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 autogroup dr-x------ 2 faculty faculty 0 Jan 19 11:17 fdinfo
-r-------- 1 faculty faculty 0 Jan 19 11:17 auxv -rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 gid_map
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 cgroup -r-------- 1 faculty faculty 0 Jan 19 11:17 io
--w------- 1 faculty faculty 0 Jan 19 11:17 clear_refs -r--r--r-- 1 faculty faculty 0 Jan 19 11:17 limits
-r--r--r-- 1 faculty faculty 0 Jan 18 17:48 cmdline -rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 loginuid
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 comm
dr-x------ 2 faculty faculty 0 Jan 19 11:17 map_files
-r--r--r-- 1 faculty faculty 0 Jan 19 02:46 maps
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 coredump_filter
-rw------- 1 faculty faculty 0 Jan 19 11:17 mem
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 cpuset
How to get additional information about process
which is running – Collect System Information
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 mountinfo -r--r--r-- 1 faculty faculty 0 Jan 19 11:17 schedstat
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 mounts -r--r--r-- 1 faculty faculty 0 Jan 19 11:17 sessionid
-r-------- 1 faculty faculty 0 Jan 19 11:17 mountstats
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 setgroups
dr-xr-xr-x 6 faculty faculty 0 Jan 19 11:17 net
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 smaps
dr-x--x--x 2 faculty faculty 0 Jan 19 11:17 ns
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 numa_maps -r-------- 1 faculty faculty 0 Jan 19 11:17 stack
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 oom_adj -r--r--r-- 1 faculty faculty 0 Jan 18 17:48 stat
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 oom_score -r--r--r-- 1 faculty faculty 0 Jan 19 11:17 statm
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 oom_score_adj -r--r--r-- 1 faculty faculty 0 Jan 18 17:48 status
-r-------- 1 faculty faculty 0 Jan 19 11:17 pagemap
-r-------- 1 faculty faculty 0 Jan 19 11:17 syscall
-r-------- 1 faculty faculty 0 Jan 19 11:17 personality
dr-xr-xr-x 33 faculty faculty 0 Jan 19 11:17 task
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 projid_map
lrwxrwxrwx 1 faculty faculty 0 Jan 19 02:46 root -> / -r--r--r-- 1 faculty faculty 0 Jan 19 11:17 timers
-rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 sched -rw-r--r-- 1 faculty faculty 0 Jan 19 11:17 uid_map
-r--r--r-- 1 faculty faculty 0 Jan 19 11:17 wchan
faculty@faculty-OptiPlex-3040:/proc/29593$
How to get additional information about process
which is running – Collect System Information
• Most files with its content is described here
File Content
clear_refs Clears page referenced bits shown in smaps output
cmdline Command line arguments
cpu Current and last cpu in which it was executed
cwd Link to the current working directory
environ Values of environment variables
exe Link to the executable of this process
fd Directory, which contains all file descriptors
maps Memory maps to executables and library files
mem Memory held by this process
How to get additional information about process
which is running – Collect System Information
File Content
root Link to the root directory of this process
stat Process status
statm Process memory status information
status Process status in human readable form
wchan Present with CONFIG_KALLSYMS=y: it shows the kernel function symbol the
task is blocked in - or "0" if not blocked
Pagemap Page table
stack Report full stack trace, enable via CONFIG_STACKTRACE
Smaps an extension based on maps, showing the memory consumption of each
mapping and flags associated with it
numa_maps an extension based on maps, showing the memory locality and binding
policy as well as mem usage (in pages) of each mapping
How to get additional information about process
which is running – Collect System Information
File Content
oom_adj & Adjust the oom-killer (Out-Of_Memory) score
oom_score_adj
oom_score Display current oom-killer score
io Display the IO accounting fields
coredump_filter Core dump filtering settings
mountinfo Information about mounts
comm & common content info about the parent task and each of the child task e.g.
/task/<tid>/com on web browser there may be multiple windows each of which is child task
m
/task/<tid>/childr Information about task children. For each process there may be multiple
en child task, hence for each of the child task a subdirectory with process ID of
child i.e. <tid> is created user /proc/<pid>/task/<tid>
How to get additional information about process
which is running – Collect System Information
File Content
/fdinfo/<fd> Information about opened file (fd is file descriptor)
map_files Information about memory mapped files
timerslack_ns Task timerslack value
patch_state Livepatch patch operation state

• How each file is structure with field names and use can be found at:
https://www.kernel.org/doc/Documentation/filesystems/proc.txt
Inter-process Communication
using Pipe
Inter-Process Communication
• Inter-Process Communication(IPC) is the generic term describing how
two processes may exchange information with each other.
• In general, the two processes may be running on the same machine
or on different machines
• This communication may be an exchange of data for which two or
more processes are cooperatively processing the data or
synchronization information to help two independent, but related,
processes schedule work so that they do not destructively overlap.
Inter-Process Communication Methods
• Local  Processes running on the same machine
• Pipe ----> We will be focusing on this today
• Signal
• MultiProcessing (MP) in multi-core/multi-processor architecture
• Distributed  Processes running on different machines
• Message Passing Interface (MPI)
Pipes
• Pipes are an interprocess communication mechanism that allow two
or more processes to send information to each other.
• commonly used from within shells to connect the standard output of one
utility to the standard input of another.
• For example, here’s a simple shell command that determines how many users
there are on the system:
$ who | wc -l
• The who utility generates one line of output per user. This output is then
“piped” into the wc utility, which, when invoked with the “-l” option, outputs
the total number of lines in its input.
Pipes

who pipe wc

Bytes from “who” flow through the pipe to “wc”

A simple pipe
Pipes
• It’s important to realize that both the writer process and the reader
process of a pipeline execute concurrently;
• a pipe automatically buffers the output of the writer and suspends the writer
if the pipe gets too full.
• Similarly, if a pipe empties, the reader is suspended until some more output
becomes available.
• All versions of UNIX support unnamed pipes, which are the kind of
pipes that shells use.
• System V also supports a more powerful kind of pipe called a named
pipe.
Unnamed Pipes: pipe() System Call
• An unnamed pipe is a unidirectional communications link that
automatically buffers its input ( the maximum size of the input varies
with different versions of UNIX, but is approximately 5K ) and may be
created using the pipe() system call.
• Each end of a pipe has an associated file descriptor:
• The “write” end of the pipe may be written to using write()
• The “read” end may be read from using read()
• When a process has finished with a pipe’s file descriptor. it should
close it using close()
• Note read(), write and close() are unbuffered I/O System Calls that we
have studied earlier
Unnamed Pipes: pipe() System Call
int pipe( int fd[2] )
• pipe() creates an unnamed pipe and returns two file descriptors:
• The descriptor associated with the “read” end of the pipe is stored in fd[0],
• The descriptor associated with the “write” end of the pipe is stored in fd[1].
• If a process reads from a pipe whose “write” end has been closed,
the “read()” call returns a value of zero, indicating the end of input.
• If a process reads from an empty pipe whose “write” end is still open,
it sleeps until some input becomes available.
Unnamed Pipes: pipe() System Call
• If a process tries to read more bytes from a pipe that are present, all of the
current contents are returned and read() returns the number of bytes
actually read.
• if a process writes to a pipe whose “read” end has been closed, the write
fails and the writer is sent a SIGPIPE signal. the default action of this signal
is to terminate the receiver.
• If a process writes fewer bytes to a pipe than the pipe can hold, the write()
is guaranteed to be atomic; that is, the writer process will complete its
system call without being preempted by another process.
• If the kernel cannot allocate enough space for a new pipe, pipe() returns a
value of -1; otherwise, it returns a value of 0.
Unnamed Pipes: pipe() System Call
• Assume that the following code was executed:
int fd[2];
pipe(fd);
data structure as shown below will be created

fd[0] Write End


Pipe
Read End
fd[1]
Unnamed Pipes: pipe() System Call
• Pipe are 1-way communication that means for bidirectional (2-way)
communication between parent and child you need 2 pipes
int fd1[2], fd2[2];
pipe(fd1); pipe(fd2);

fd1[0] Parent Write End fd2[0] Child Write End


Pipe Pipe
Child Read End Parent Read End
fd1[1] fd2[1]
Unnamed Pipes: pipe() System Call
• Unnamed pipes are usually used for communication between a
parent process and its child, with one process writing and the other
process reading.
• The typical sequence of events for such a communication is as
follows:
1. The parent process creates an unnamed pipe using pipe().
2. The parent process forks.
3. The writer closes its “read” end of the pipe, and the designated reader
closes its “write” end of the pipe.
4. The processes communicate by using write() and read() system calls.
5. Each process closes its active pipe descriptor when it’s finished with it.
Unnamed Pipes: pipe() System Call
• Please note : Bidirectional communication is only possible by if ( fork() == 0 ) /* Child, write */
using two pipes.
{
• Here’s a small program that uses a pipe to allow the parent to
read a message from its child: close(fd[READ]); /* Close unused end */
$ cat talk.c ---> list the program. write(fd[WRITE], phrase, strlen(phrase)+1); /* Send */
#include <stdio.h> close(fd[WRITE]); /* Close used end */
#define READ 0 /* The index of the “read” end of the pipe }
*/ else /* Parent, reader */
#define WRITE 1 /* The index of the “write” end of the {
pipe */
char* phrase =“Stuff this in your pipe and smoke it”; close(fd[WRITE]); /* Close unused end */
int main(void) bytesRead = read( fd[READ], message, 100 ); /* Receive */
{ printf(“Read %d bytes: %s \n”, bytesRead, message );
int fd[2], bytesRead; close(fd[READ]); /* Close used end */
char message[100]; /* Parent process’ message buffer */ }
pipe(fd); /* Create an unnamed pipe */ }
Unnamed Pipes: pipe() System Call
• The child included the phrase’s NULL terminator as part of the
message so that the parent could easily display it.
write(fd[WRITE], phrase, strlen(phrase)+1);  length+1
• When a writer process sends more than one variable-length message
into a pipe, it must use a protocol to indicate to the reader the
location for the end of the message.
• Methods for such indication include :
• sending the length of a message(in bytes) before sending the message itself
• ending a message with a special character such as a new line or a NULL
Unnamed Pipes: pipe() System Call
• UNIX shells use unnamed pipes to build pipelines, dup2( fd[WRITE], 1); /* Duplicate used end to stdout */
connecting the standard output of the first to the standard
input of the second. close( fd[WRITE] ); /* Close original used end */
#include <stdio.h> execlp( argv[1], argvp[1], NULL ); /* Execute writer program
*/
#define READ 0
perror( “connect” ); /* Should never execute */
#define WRITE 1
}
int main( int argc, char *argv[] )
else /* Child, reader */
{
{
int fd[2];
close( fd[WRITE] ); /* Close unused end */
pipe(fd); /* Create an unnamed pipe */
dup2( fd[READ], 0 ); /* Duplicate used end to stdin */
if ( fork()!=0 ) /* Parent, writer */
close( fd[READ] ); /* Close original used end */
{
execlp( argv[2], argv[2], NULL ); /* Execute reader program
close( fd[READ] ); /* Close unused end */ */
perror( “connect” ); /* Should never execute */
}
}
Unnamed Pipes: pipe() System Call
$ who ---> execute “who” by itself.
gglass ttyp0 Feb 15 18:15 (xyplex_3)

$ connect who wc ---> pipe “who” through “wc”.


1 6 57 …1 line, 6 words, 57 chars.
Environment Variables
faculty@faculty-OptiPlex-3040:~/IT628-SystemProgramming$ env Set User Defined Environment Variable:
SESSION=ubuntu $ course=it628
TERM=xterm-256color $ export course
SHELL=/bin/bash $ env | grep course
USER=faculty
course=it628
LD_LIBRARY_PATH=/home/faculty/torch/install/lib:
$
PATH=/home/faculty/ApacheSpark/spark/bin:/home/faculty/torch/install/
bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
:/usr/local/games:/snap/bin
PWD=/home/faculty/IT628-SystemProgramming
HOME=/home/faculty
LANGUAGE=en_IN:en
LOGNAME=faculty
OLDPWD=/home/faculty
_=/usr/bin/env
faculty@faculty-OptiPlex-3040:~/IT628-SystemProgramming$
Environment Variables
#include <stdio.h>
int main(int argc, char*argv[],
char*env[])
{

char **ptr;

for(ptr=env; *ptr != 0; ptr++)


printf("%s\n",*ptr);

}
Environment Variables
char *getenv(const char *name); int setenv(const char *name, const char
name – search for this name in *value, int overwrite);
environment of current process Adds or change name parameter and its
Returns pointer to value value
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
main() main()
{ {
printf("SHELL = %s\n", getenv("SHELL")); setenv("HOST", "new host name", 1);
printf("HOST = %s\n", getenv("HOST")); printf("HOST = %s\n", getenv("HOST"));
} }

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy