Unit I: Introduction to Linux
Linux Architecture, Kernel Features, System Calls vs. Library
Functions
Linux Architecture The Linux architecture is a layered system. At its
core is the Kernel, which interacts directly with the hardware.
Surrounding the kernel is the Shell, which provides a command-line
interface for users. Applications and user programs operate on top of the
shell.
Kernel: The central component of the OS. It manages system
resources, handles processes, and provides a low-level interface to
hardware.
System Calls: These are the interface between user-space
programs and the kernel. They are the only way for a user program
to request a service from the OS.
Shell: A command-line interpreter that allows users to interact with
the OS. Examples include Bash, Zsh, and Csh.
User Applications: All the programs and utilities that run on the
system (e.g., text editors, web browsers, compilers).
Kernel Features The Linux kernel is a monolithic kernel, meaning that
all its services (like process management, memory management, and file
systems) are compiled into a single, large program. Key features include:
Preemptive multitasking: The kernel can interrupt a running
process and give control to another, ensuring fair CPU time
distribution.
Virtual memory: A memory management technique that provides
each process with its own dedicated memory space, protecting
processes from each other.
Demand paging: A form of virtual memory that loads only the
needed parts of a program into physical memory.
Shared libraries: Code that can be loaded into memory and
shared among multiple programs, reducing memory usage.
System Calls vs. Library Functions
System Calls:
o Directly interact with the kernel.
1
o Provide a low-level interface to hardware.
o Slower due to the context switch from user mode to kernel
mode.
o Examples: open(), read(), write(), fork().
Library Functions:
o Provide a higher-level, more user-friendly interface.
o Often wrap one or more system calls.
o Run in user mode, making them faster than system calls.
o Examples: printf(), scanf(), fopen(). printf() uses the write()
system call internally to output data.
Basic Commands
Here are some of the most fundamental Linux commands:
echo: Prints text to the terminal.
o echo "Hello, world!"
passwd: Changes a user's password.
o passwd
uname: Prints system information.
o uname -a (shows all system info)
date: Displays or sets the system date and time.
o date
cal: Displays a calendar.
o cal 2025
man: Displays the manual page for a command.
o man ls
Simple Filters and Pipes
Filters: Programs that take input from standard input, perform some
operation, and send the result to standard output.
cat: Concatenates files and prints to standard output.
o cat file1.txt file2.txt
grep: Searches for patterns in files.
2
o grep "error" log.txt (finds lines with "error" in log.txt)
awk: A powerful pattern-scanning and text-processing language. It's
especially useful for column-based data.
o awk '{print $2}' file.txt (prints the second column of file.txt)
Pipes (|): Used to redirect the standard output of one command to the
standard input of another. This chains commands together.
ls -l | grep "Aug" (lists files and pipes the output to grep to find files
modified in August)
Writing awk Scripts An awk script can be stored in a file and executed.
Example Script (process_data.awk):
Awk
BEGIN { print "--- Employee Report ---" }
{ print "Name:", $1, "\tSalary:", $3 }
END { print "--- End of Report ---" }
Execution:
Bash
awk -f process_data.awk employees.txt
This script would process a file employees.txt and format its output.
GNU Development Tools: make Utility
make: A build automation tool that automatically builds executable
programs and libraries from source code by reading a Makefile.
Makefile: A file that contains a set of rules. Each rule specifies a target,
its dependencies, and the commands to create the target.
Example Makefile for a simple C program:
Makefile
hello: main.o factorial.o
gcc main.o factorial.o -o hello
main.o: main.c
gcc -c main.c
3
factorial.o: factorial.c
gcc -c factorial.c
clean:
rm -f *.o hello
To build the program, you just run make. To clean up the build files,
you run make clean.
Static and Shared Libraries
Static Libraries (.a files): A collection of object files (.o). The
linker copies the code from the library directly into the final
executable at link time.
o Advantage: No external dependencies at runtime.
o Disadvantage: Larger executable size, difficult to update.
o Creation: ar rcs libmylib.a file1.o file2.o
Shared Libraries (.so files): The library's code is loaded into
memory only once at runtime and can be shared by multiple
programs.
o Advantage: Smaller executable size, easier to update (just
replace the .so file).
o Disadvantage: The executable depends on the library
existing on the system.
o Creation: gcc -shared -o libmylib.so file1.o file2.o
Unit II: Introduction to File System
Basics of File System Implementation
A file system is a method for storing and organizing computer files and the
data they contain. The core components are:
Boot block: Contains the boot loader code to start the OS.
Superblock: Contains metadata about the entire file system (e.g.,
total number of blocks, number of free blocks).
i-node blocks: Store a list of i-nodes.
Data blocks: Contain the actual file content.
4
i-nodes (Index Nodes) An i-node is a data structure that stores
metadata about a file or directory. This metadata includes:
File type (regular file, directory, link, etc.)
Permissions (read, write, execute)
Owner and group IDs
Timestamps (creation, modification, last access)
Number of links (hard links)
Size of the file
Pointers to the data blocks where the file content is stored. Each file
and directory has a unique i-node number.
File Permissions, Attributes, and Types
File Permissions Permissions are represented by three sets of a three-
character code: rwx (read, write, execute).
Owner (u): Permissions for the file's owner.
Group (g): Permissions for the user's group.
Others (o): Permissions for all other users.
chmod: The command used to change these permissions. It can be
used with symbolic or octal notation.
o Octal: chmod 755 file.txt (owner has rwx, group and others
have r-x)
r=4, w=2, x=1 (e.g., rwx = 4+2+1=7)
o Symbolic: chmod u+x file.txt (adds execute permission for
the owner)
File Types
-: Regular file
d: Directory
l: Symbolic link
b: Block device
c: Character device
p: Named pipe (FIFO)
s: Socket
5
umask The umask command sets the default permissions for newly
created files and directories. It works by subtracting the umask value from
the default permissions. The default for files is 666 (rw-rw-rw-) and for
directories is 777 (rwxrwxrwx).
Example: If umask is 022, new files will have permissions 666 - 022
= 644 (rw-r--r--).
Hierarchical File System Structure
The Linux file system is organized as a single inverted tree, starting from
the root directory (/).
/bin: Essential user command binaries.
/etc: Host-specific configuration files.
/home: Home directories for user accounts.
/lib: Essential shared libraries.
/usr: Secondary hierarchy for read-only user data.
/var: Variable data (e.g., logs, spool files).
Hard Links and Symbolic Links
Hard Link: A new directory entry that points to the same i-node as
the original file. All hard links to a file are indistinguishable; they are
all equally valid names for the file. Deleting a hard link doesn't
delete the file's data until the last hard link is removed.
o Command: ln original_file hard_link
Symbolic (Soft) Link: A new file that contains the path to the
original file. It's a pointer to another file. Deleting the original file
breaks the symbolic link.
o Command: ln -s original_file symbolic_link
File Handling using System Calls
These are low-level system calls for file manipulation.
open(): Creates or opens a file and returns a file descriptor.
o int fd = open("file.txt", O_RDWR | O_CREAT, 0644);
read(): Reads data from a file descriptor into a buffer.
o ssize_t bytes_read = read(fd, buffer, 1024);
write(): Writes data from a buffer to a file descriptor.
6
o ssize_t bytes_written = write(fd, "hello", 5);
close(): Closes a file descriptor.
o close(fd);
dup() and dup2(): Duplicate file descriptors. dup2() is more
powerful as it allows specifying the new descriptor number.
o dup(fd) creates a new descriptor pointing to the same file.
o dup2(old_fd, new_fd) makes new_fd point to the same file as
old_fd.
fcntl(): Manipulates a file descriptor (e.g., change file status flags).
stat(): Gets file status information (fills a struct stat with details like
i-node, permissions, size).
Directory API
These functions are used to access the contents of directories.
opendir(): Opens a directory stream and returns a pointer to the
directory.
o DIR *dirp = opendir(".");
readdir(): Reads the next directory entry from the stream and
returns a pointer to a struct dirent.
o struct dirent *entry;
o while ((entry = readdir(dirp)) != NULL) { ... }
closedir(): Closes a directory stream.
o closedir(dirp);
Unit III: Processes and Signals
Processes
Process Concept: A process is an instance of a running program. It
includes the program code, its data, and its state (e.g., program counter,
registers).
Process Attributes: Each process has a unique Process ID (PID),
a Parent Process ID (PPID), user ID (UID), group ID (GID), and other
attributes.
7
Process Creation (fork()) The fork() system call creates a new process,
called the child process, which is an exact copy of the calling parent
process.
It returns 0 in the child process.
It returns the child's PID in the parent process.
It returns -1 on failure.
vfork(): Similar to fork(), but the parent process is suspended, and the
child process shares the parent's memory space. It is intended for use
with exec().
exec() Family of System Calls The exec() calls replace the current
process's memory space with a new program. The process ID remains the
same.
execl(), execv(), execle(), execve(), execlp(), execvp().
Example: execlp("ls", "ls", "-l", NULL);
Waiting for a Process (wait(), waitpid()) The wait() and waitpid() calls
allow a parent process to wait for its child process to terminate.
wait(): Waits for any child process to terminate.
waitpid(): Waits for a specific child process, identified by its PID.
Process Termination (exit(), _exit(), atexit())
exit(): A library function that performs cleanup (like flushing I/O
buffers) before calling _exit().
_exit(): A system call that immediately terminates the process.
atexit(): Registers a function to be called just before the process
terminates normally.
Zombie Process: A terminated child process whose parent has not yet
called wait() or waitpid(). The process exists only as a process table entry,
containing its exit status. Orphan Process: A process whose parent has
terminated. The orphan process is then adopted by the init process (PID
1).
Signals
Introduction to Signals: Signals are software interrupts sent to a
process to notify it of an event. They are a form of limited Inter-Process
Communication (IPC).
Signal Generation and Handling
8
kill(): Sends a signal to a process or process group.
raise(): Sends a signal to the calling process itself.
signal(): Installs a signal handler function for a specific signal.
o void (*signal(int sig, void (*handler)(int))) (int);
sigaction(): A more robust and powerful alternative to signal(). It
allows for more control over signal handling.
alarm(): Sets a timer that sends a SIGALRM signal to the process
after a specified number of seconds.
pause(): Suspends the process until a signal is received.
abort(): Sends a SIGABRT signal to the process, causing it to
terminate abnormally.
sleep(): Suspends the process for a specified number of seconds.
Signal Handlers A signal handler is a function that is executed when a
specific signal is received.
Example: void my_handler(int signum) { ... }
Unit IV: Inter Process Communication-1
Pipes
Pipes: A unidirectional (one-way) communication channel between two
processes.
Unnamed Pipes: Used for communication between a parent and its child
process.
API: pipe(int filedes[2]) creates a pipe. filedes[0] is for reading,
filedes[1] is for writing.
Example: A parent creates a pipe, forks, and then one process
reads from the pipe while the other writes to it.
Named Pipes (FIFOs): A file on the file system that allows
communication between unrelated processes.
Creation: mkfifo("my_fifo", 0666) or mkfifo my_fifo from the shell.
Usage: Processes can open the FIFO file for reading and writing, just
like a regular file.
System V IPC
9
System V IPC provides three main mechanisms: Message Queues,
Semaphores, and Shared Memory.
Common Data Structures: All three mechanisms use a key_t (a
unique key) to identify the IPC object, and struct ipc_perm to store
permissions.
System Calls:
o msgget(), semget(), shmget(): To get or create an IPC object.
o msgctl(), semctl(), shmctl(): To control an IPC object (e.g.,
delete it).
Multi-Threading using PThreads
Threads vs. Processes | Feature | Processes | Threads | | :--- | :--- | :--- | |
Memory | Separate memory space | Share the same memory space | |
Resources | Independent | Share files, data, etc. | | Overhead | High |
Low | | Creation | fork() | pthread_create() | | Communication | IPC
mechanisms (pipes, etc.) | Direct memory access |
POSIX Thread (PThread) APIs
pthread_create(): Creates a new thread.
pthread_join(): Waits for a specific thread to terminate.
pthread_exit(): Terminates the calling thread.
Thread Synchronization Since threads share memory, they need
synchronization mechanisms to prevent race conditions.
Mutexes (Mutual Exclusion Locks): A lock that ensures only one
thread can access a critical section of code at a time.
o pthread_mutex_init(), pthread_mutex_lock(),
pthread_mutex_unlock().
POSIX Semaphores: A synchronization tool for controlling access
to a common resource.
o sem_init(), sem_wait(), sem_post().
Condition Variables: Used to block a thread until a specific
condition is true. They are always used with a mutex.
o pthread_cond_init(), pthread_cond_wait(),
pthread_cond_signal().
Socket Programming
10
Socket API: The standard API for network communication. A socket is an
endpoint for communication.
Simple TCP Client/Server:
o Server: socket() -> bind() -> listen() -> accept() ->
read()/write()
o Client: socket() -> connect() -> write()/read()
Simple UDP Client/Server:
o Server: socket() -> bind() -> recvfrom() -> sendto()
o Client: socket() -> sendto() -> recvfrom()
Message Queues
Message Queues: A linked list of messages stored within the kernel.
Processes can place messages onto the queue or retrieve them.
System Calls:
o msgget(): Creates or gets a message queue.
o msgsnd(): Sends a message to the queue.
o msgrcv(): Receives a message from the queue.
o msgctl(): Controls the queue (e.g., delete it).
Client-Server Example: A client sends a request message with its
PID, and the server receives it, processes it, and sends a reply
message back to the client using its PID.
Unit V: Inter Process Communication-2
System V Shared Memory
Shared Memory: The fastest IPC mechanism. It allows two or more
processes to share a region of memory. Once set up, communication is as
fast as reading and writing to memory.
APIs:
o shmget(key_t key, size_t size, int shmflg): Creates or accesses
a shared memory segment.
o shmat(int shmid, const void *shmaddr, int shmflg): Attaches
the shared memory segment to the process's address space.
11
o shmdt(const void *shmaddr): Detaches the shared memory
segment.
o shmctl(int shmid, int cmd, struct shmid_ds *buf): Controls the
shared memory segment (e.g., delete it).
Sample Application: A process creates a shared memory segment
and writes data to it. Another process attaches to the same segment
and reads the data.
System V Semaphores
Semaphores: Used to synchronize access to shared resources, often
used in conjunction with shared memory.
A semaphore is a variable that can be in one of two states: "locked"
or "unlocked." It's used to manage access to a critical section.
APIs:
o semget(key_t key, int nsems, int semflg): Creates or accesses
a set of semaphores.
o semop(int semid, struct sembuf *sops, size_t nsops): Performs
a semaphore operation (e.g., wait/decrement,
signal/increment).
o semctl(int semid, int semnum, int cmd, ...): Controls a
semaphore.
Sample Application: Two processes use a semaphore to protect a
shared memory segment. One process "waits" on the semaphore
(decrements its value) before accessing the shared memory, and
the other process "signals" (increments its value) after it is done.
This prevents both processes from writing to the memory at the
same time.
============================================
============================================
============================================
=======
12
Unit I: Introduction to Linux
Linux architecture consists of a layered design with hardware at the
bottom, the monolithic but modular Linux kernel in the middle, and
system libraries, user-space utilities, shells, and applications on top,
communicating via system calls and standard interfaces such as the GNU
C Library (glibc) to access kernel services. The kernel manages memory,
processes, filesystems, devices, networking, and IPC, while user
applications run in user mode and rely on the kernel for privileged
operations, providing security and isolation between processes and the
hardware.
Kernel features include support for loadable kernel modules, preemptive
multitasking, virtual memory, a rich set of filesystems, POSIX-compliant
process and signal handling, and a uniform “everything is a file” I/O
model, which simplifies device and resource access through file
descriptors and standard system calls. The separation between user mode
and kernel mode is enforced by the CPU, and transitions happen through
controlled system calls, interrupts, and exceptions to maintain protection
and stability.
System calls vs library functions: a system call is the privileged entry
point into the kernel to request OS services (e.g., fork, execve, open),
incurring a user–kernel mode switch; a library function is code linked in
user space that may wrap system calls or perform pure user-space work,
typically faster when no kernel transition is needed and usually more
portable across systems. Library calls like printf may use buffered I/O and
call write under the hood, whereas direct write is a system call; system
calls are less portable and incur context-switch overhead, while library
calls are portable and easier to use.
Basic commands: echo prints strings and variables; passwd changes a
user password interactively; uname prints system information (kernel,
machine, etc.); date shows or sets date/time with format specifiers; cal
displays calendars for a given month or year; man opens manual pages
13
for commands and system/library calls with sections like 1 (user cmds), 2
(syscalls), 3 (libc). For instance, uname -a prints kernel name, version, and
architecture; date "+%F %T" prints ISO date-time; cal 8 2025 shows
August 2025; man 2 open shows the open system call and man 3 printf
shows the libc function.
Filters and pipes: a filter reads stdin, transforms, and writes stdout, often
connected by pipes using | to form processing chains; classic filters
include cat to concatenate and display files, grep to search by regex
patterns, and awk for pattern scanning and action processing over
structured text . grep supports options like -i (case-insensitive), -w (whole
word), -n (line numbers), -c (count), -o (only match), and -E (EREs) to
refine searches over streams or files in pipelines such as dmesg | grep -i
error . awk programs consist of pattern { action } pairs, with built-in fields
$1, $2, …, NF and variables like FS and OFS; awk can filter columns,
compute aggregates, and format reports, and is well-suited for log and
CSV processing in simple scripts .
GNU development tools: make automates building multi-source C projects
using rules, dependencies, and macros, rebuilding only what changed to
speed up development; typical patterns compile .c to .o then link to
executable with variables like CC, CFLAGS, LDFLAGS. Building static
libraries uses ar to create archives (libfoo.a) of object files and link them
statically, while shared libraries (.so) are position-independent code built
with -fPIC and -shared, loaded via the dynamic linker at runtime, with
search paths controlled by rpath, ldconfig, and LD_LIBRARY_PATH. gcc
options -shared, -fPIC, -static, and -Wl,options (pass to linker) govern
shared/static builds; correct SONAMEs enable ABI management so
applications pick the right version at load time.
Unit II: Introduction to File System
Unix/Linux filesystem basics: the hierarchy is a single rooted tree at “/”,
where everything is a file (regular files, directories, devices, FIFOs,
sockets), and each file is identified by an inode that stores metadata and
pointers to data blocks; pathnames are directory entries mapping names
to inode numbers. Directories are special files listing name-to-inode
mappings; removing a name decrements the link count in the inode, and
when it reaches zero and no process holds it open, space is reclaimed; this
design underlies hard links and unlink semantics.
Inodes and permissions: an inode stores ownership (uid/gid), mode bits
(file type and rwx permissions), timestamps, size, and pointers;
permissions are three triplets for user, group, and others, with optional
special bits setuid, setgid, and sticky, determining access checks enforced
14
by the kernel when opening and operating on files. File types include
regular files, directories, character/block devices, FIFOs, and sockets,
visible via ls -l or stat; metadata can be inspected by stat system call or
utilities.
Changing attributes: chmod changes permissions using symbolic (u,g,o,
+,-,=) or octal notation; umask sets the default permission mask
subtracted from requested modes on create; chown and chgrp adjust
ownership subject to privileges and filesystem semantics. umask 022
leads to new files of 644 and directories 755 when programs request
666/777 default modes; sticky bit on world-writable directories like /tmp
prevents non-owners from deleting others’ files.
Hard links and symbolic links: a hard link creates another directory entry
pointing to the same inode, sharing data and link count; removing any
name decrements link count but data persist until count is zero; hard links
cannot cross filesystems or target directories in most UNIX variants. A
symbolic link is a small special file storing a pathname that the kernel
resolves at access time, can cross filesystems, and can dangle if the
target is removed; modifying the target reflects through symlinks because
they reference the path not the inode directly.
File handling via system calls: files are accessed via integer file
descriptors obtained by open, operated with read, write, lseek, and closed
by close; dup and dup2 duplicate descriptors, while fcntl manipulates
descriptor and status flags like FD_CLOEXEC or O_NONBLOCK and can
duplicate descriptors with F_DUPFD. stat and fstat retrieve file status
(mode, size, times, link count); O_CREAT creates files, O_TRUNC truncates,
O_APPEND appends; error reporting uses errno and -1 returns, requiring
careful checking in robust code.
Directory API: directory traversal uses opendir to obtain a DIR stream,
readdir to iterate entries returning struct dirent with fields like d_name
and possibly d_type, rewinddir to restart, and closedir to release
resources; d_ino and d_name are portable fields, while d_type may be
absent depending on filesystem and libc, requiring lstat to determine
types portably. readdir returns NULL at end or on error and is not thread-
safe unless using readdir_r (now deprecated) or external synchronization;
modern code prefers readdir with appropriate locking and careful error
checks.
Unit III: Processes and Signals
Process concepts: a process is an instance of a program with its own
address space, resources, and execution context, managed by the kernel
scheduler which supports multitasking and isolation; process attributes
15
include PID, PPID, UID/GID, priority, state, memory mappings, open file
descriptors, and environment. The kernel provides system calls to create,
exec, wait, and terminate processes in compliance with POSIX, ensuring
resource accounting and cleanup on exit.
Process creation and control: fork creates a child as a near-identical copy
of the parent with copy-on-write memory; vfork creates a child that shares
the address space temporarily until exec/exit to optimize creation for
immediate exec, requiring caution to avoid undefined behavior in the
parent’s memory; exec family (execl, execv, execve, etc.) overlays the
current process image with a new program. The parent can wait for child
termination using wait/waitpid to collect exit status and avoid zombies; a
child calling _exit/exit terminates and returns status to parent, while atexit
registers user-space cleanup handlers invoked on normal process exit.
Zombie and orphan processes: a zombie is a child that has exited but
whose parent has not yet waited, leaving an entry in the process table
until reaped; an orphan is a child whose parent exited first, causing
init/systemd to adopt it and reap it later; proper use of wait in parents and
SIGCHLD handlers prevents zombie accumulation in long-lived daemons.
Zombies consume minimal resources but indicate missing wait logic;
orphans continue to run normally under the new parent and are
eventually reaped at termination.
Signals: signals are asynchronous notifications to processes for events like
interrupts, termination requests, or alarms; handling uses signal or the
more robust sigaction to set handlers, mask, and flags (SA_RESTART,
SA_NOCLDWAIT), while kill sends a signal to a process or process group,
and raise sends a signal to self. alarm schedules SIGALRM after a given
number of seconds; pause suspends until a signal arrives; abort sends
SIGABRT to cause abnormal termination; sleep suspends for a duration;
proper handlers must be async-signal-safe and typically set flags checked
in the main loop to avoid reentrancy issues.
Unit IV: Inter Process Communication-1
Pipes: unnamed pipes are kernel buffers created with pipe() returning two
file descriptors for read and write, enabling one-way communication
between related processes, typically used with fork and dup2 to wire child
stdin/stdout in pipelines; named pipes (FIFOs) are special files created
with mkfifo accessible by unrelated processes for stream-based
communication. Programs implement producer-consumer patterns by
writing to and reading from these descriptors with standard read/write,
handling EPIPE and SIGPIPE on broken pipes appropriately and using
nonblocking or select/poll when needed.
16
System V IPC overview: System V message queues, semaphores, and
shared memory use keys (ftok) and identifiers (msgget, semget, shmget)
with control operations (msgctl, semctl, shmctl) to manage objects across
processes; message queues support typed messages with
msgsnd/msgrcv, semaphores provide counting or binary synchronization
with sembuf operations via semop, and shared memory segments attach
with shmat for high-performance data sharing. Common data structures
include msqid_ds, shmid_ds, and sembuf; permissions and lifetimes are
maintained by the kernel, and cleanup is essential to avoid leaks after
crashes.
POSIX threads vs processes: threads share address space and most
resources within a process, enabling lighter-weight concurrency than
processes which have separate address spaces; Pthreads APIs include
pthread_create to spawn threads, pthread_join to wait, and
synchronization primitives such as pthread_mutex_t for mutual exclusion,
pthread_cond_t for condition variables, and POSIX semaphores (sem_t) for
counting synchronization. Correct synchronization prevents data races and
deadlocks, using mutexes to protect shared data, condition variables to
coordinate state changes, and semaphores for resource counting;
example thread functions receive a void* argument and return void*
status to be joined later.
Socket programming: the BSD/POSIX socket API provides network
communication endpoints with socket(), bind(), listen(), accept() for TCP
servers and connect() for clients; UDP uses datagram sockets with
sendto/recvfrom without connection setup, trading reliability for low
overhead. A simple TCP server creates a socket(AF_INET, SOCK_STREAM),
binds to an address/port, listens, and accepts clients in a loop, while a TCP
client connects and exchanges data using send/recv; proper error handling
and address conversion with getaddrinfo simplify portability between
IPv4/IPv6.
Message queues: System V message queues allow processes to exchange
variable-length messages with types, enabling selective retrieval; msgsnd
enqueues and msgrcv dequeues with blocking or nonblocking options,
with queue limits and permissions enforced by the kernel; typical patterns
implement sender/receiver pairs or client/server request-response
semantics. Ensuring msgrcv type matching and handling EAGAIN for
nonblocking operations are key to robust programs; queues must be
removed with msgctl(IPC_RMID) to prevent resource leaks.
Unit V: Inter Process Communication-2
17
System V shared memory: shmget creates or obtains a shared memory
segment identified by a key; shmat attaches it into a process’s address
space and returns a pointer for direct memory access; shmdt detaches,
and shmctl controls/queries and can mark for removal, making shared
memory the fastest IPC for large data. Because multiple processes can
read and write concurrently, synchronization is required to prevent races,
typically with semaphores or futex-based mechanisms layered on top, and
careful attention to cache coherence and memory barriers in highly
concurrent designs.
System V semaphores: semget creates a semaphore set; semop performs
atomic operations described by struct sembuf to decrement (P), increment
(V), or wait-on-zero; semctl configures and queries semaphore values and
permissions, enabling inter-process locking and coordination over shared
resources or shared memory regions. Typical sample applications pair
shared memory buffers with semaphores to implement producer-
consumer queues, ensuring that producers wait when buffers are full and
consumers wait when empty, with robust cleanup on exit paths.
Sample applications with shared memory and semaphores demonstrate a
ring buffer using one semaphore counting filled slots, one counting empty
slots, and a mutex-like semaphore guarding critical sections for push/pop,
achieving high throughput with minimal context-switch overhead
compared to message-based IPC. Proper handling of interruption by
signals (EINTR) and cleanup via signal handlers helps avoid orphaned IPC
objects; IPC_RMID marking combined with active attachments ensures
cleanup after last detach.
References and resources: for deeper coverage and man page details on
readdir, opendir, and directory iteration, the man7 pages explain struct
dirent fields and portability of d_type; The Open Group POSIX pages
specify opendir/readdir semantics; practical syscall tutorials cover open,
read, write, close, dup/dup2, and fcntl flags, including FD_CLOEXEC and
O_NONBLOCK patterns common in daemon code. For make and library
building, tutorials on static archives with ar and shared libraries with gcc -
shared and -fPIC outline SONAMEs, dynamic linking behavior, and
LD_LIBRARY_PATH/rpath strategies; ELF and GNU ld notes clarify -shared, -
static, and -Wl, options used in real projects.
Sources: architecture and processes overview derived from Linux/UNIX
architecture notes; syscalls vs library calls distinctions compiled from
tutorials and references; command basics, filters, and grep options from
Linux command tutorials; filesystem, inodes, links, and permissions from
Unix FS references; file and directory APIs from POSIX and man pages;
processes, zombies/orphans, and signals from programming guides; IPC
18
(pipes, System V IPC), Pthreads, sockets, and message queues from
system programming tutorials.
19