0% found this document useful (0 votes)
2 views

Unit_4_UNIX System V

System V is a major version of the Unix operating system developed by AT&T's Bell Laboratories and released in 1983, known for its influential features and inter-process communication (IPC) mechanisms such as message queues, semaphores, and shared memory. The document details the functionalities and APIs related to these IPC mechanisms, including how to create, manage, and use message queues and semaphores in Unix. It also provides examples of client-server communication using message queues and semaphore operations for process synchronization.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Unit_4_UNIX System V

System V is a major version of the Unix operating system developed by AT&T's Bell Laboratories and released in 1983, known for its influential features and inter-process communication (IPC) mechanisms such as message queues, semaphores, and shared memory. The document details the functionalities and APIs related to these IPC mechanisms, including how to create, manage, and use message queues and semaphores in Unix. It also provides examples of client-server communication using message queues and semaphore operations for process synchronization.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 73

Unit-4

UNIX System V
Unix system 5 release 1 in 1983
System V

► System V ("System Five") is one of the major versions of the Unix operating
system.

► It was originally developed by AT&T's Bell Laboratories and released in 1983.

► System V became one of the most widely used and influential Unix variants,
with many features and concepts that have been adopted into other Unix-like
systems.
► UNIX System V messages are part of the System V inter-process
communication (IPC) mechanisms, which allow processes to exchange data
and synchronize their activities.
These mechanisms include
► Message queues,
► semaphores, and
► shared memory.
Key features of System V
Key features of System V
Key features of System V
Versions and Evolutions
Versions and Evolutions
Message Queues

► Message queues were introduced in Unix system V release.


► A Message queue is a inter process communication mechanism using which one
process can communicate with another.
► It is created and managed by the kernal in response to system calls made by
processes.
► So a process which wants to receive messages can create a message queue for
itself and make sure clients know its ID and then wait for messages to come
in.
► Processes that want to communicate with the particular process should know
the message queue ID of that process and then send a message to the queue
of that process.
Two types of message queues

► 1) System V Message queues


► 2) POSIX Message queues
Unix kernal support for messages

► The UNIX kernel provides robust support for inter-process communication


(IPC) message queues, which allow processes to send and receive messages.

► Message queues in the UNIX kernel allow processes to communicate with each
other by sending and receiving messages.
Unix APIs for messages

► UNIX provides several APIs for inter-process communication (IPC), including


those specifically for message queues. The primary APIs used for handling
messages in UNIX are part of the System V IPC suite.

► The APIs (‘msgget’, ‘msgsnd’, ‘msgrcv’, ‘msgctl’) allow processes to create,


send, receive, and control message queues, enabling efficient data exchange
and synchronization between processes.

► Proper understanding and use of these APIs can significantly enhance the
capabilities of applications requiring inter-process communication.
Key functions for messages
Client server Example
Client server Example

► Server has a message queue in which client send request messages.


► Each client has a message queue in which they get response from server.
► The server listens for messages from clients, processes them, and sends back
a response, while the client sends a message and waits for a response.
► This IPC mechanism allows processes to communicate effectively in a UNIX
environment.
server
#define MSGSZ 128
struct msgbuf {
► long mtype;
► char mtext[MSGSZ];
► };
int main() {
key_t key;
int msgid;
► struct msgbuf message;
key = ftok("msgqueue", 65);
msgid = msgget(key, 0666 | IPC_CREAT); //create a message queue if not exist
► if (msgid == -1) {
► perror("msgget");
► exit(1);
► }
while (1) {
► if (msgrcv(msgid, &message, sizeof(message.mtext), 1, 0) == -1) {// Receive a message from the client
► perror("msgrcv");
► exit(1);
► }
► printf("Server received: %s\n", message.mtext);
message.mtype = 2; // Message type for the response // Prepare the response message
► snprintf(message.mtext, MSGSZ, "Message received: %s", message.mtext);
if (msgsnd(msgid, &message, sizeof(message.mtext), 0) == -1) {// Send the response message to the client
► perror("msgsnd");
► exit(1);
► }
► printf("Server sent response: %s\n", message.mtext);
► }
if (msgctl(msgid, IPC_RMID, NULL) == -1) {// Delete the message queue
► perror("msgctl");
► exit(1);
client
► #define MSGSZ 128
struct msgbuf {
► long mtype;
► char mtext[MSGSZ];
► };
► int main() {
► key_t key;
► int msgid;
► struct msgbuf message;

► key = ftok("msgqueue", 65); // Generate a unique key for the message queue
► msgid = msgget(key, 0666); // Get the identifier for the message queue
► if (msgid == -1) {
► perror("msgget");
► exit(1);
► }
► // Prepare the message to be sent to the server
message.mtype = 1; // Message type for the client to server message
► snprintf(message.mtext, MSGSZ, "Hello from client");
if (msgsnd(msgid, &message, sizeof(message.mtext), 0) == -1) {// Send the message to the server
► perror("msgsnd");
► exit(1);
► }
► printf("Client sent: %s\n", message.mtext);
► if (msgrcv(msgid, &message, sizeof(message.mtext), 2, 0) == -1) {// Receive the response message from the server
► perror("msgrcv");
► exit(1);
► }
► printf("Client received response: %s\n", message.mtext);
Semaphore
► semaphores are a mechanism for synchronizing processes.

► They are part of the System V IPC (Inter-Process


Communication) suite.

► Semaphores are provided by Kernal.

► Semaphores are visible to all processes and a process can


operate on it provided it has the permission to do so.
TWO TYPES OF SEMAPHORES

1.System V Semaphores
2) POSIX Semaphores

System V semaphores provide more functionality


compared to the simpler POSIX semaphores.
Key Concepts
The main APIs for working with semaphores are

► ‘semget()’- Create a new semaphore set or access an


existing set.

► ‘semctl()’- Perform control operations on a semaphore


set.

► ‘semop()’- Perform operations on the semaphores in a


set.
Creating and Accessing Semaphores

► Use semget() function


► #include <sys/ipc.h>
► #include <sys/sem.h>
► int semget(key_t key, int nsems, int semflg);
Semaphore Operations
► Use ‘semop()’ function
► #include <sys/types.h>
► #include <sys/ipc.h>
► #include <sys/sem.h>
► int semop(int semid, struct sembuf *sops, size_t nsops);
Semaphore Buffer Structure

► ‘struct sembuf’ structure defines a semaphore operation.

► struct sembuf {
► unsigned short sem_num; // Semaphore number in the set
► short sem_op; // Operation to be performed
► short sem_flg; // Operation flags
► };
Example

► basic example demonstrating how to create a semaphore set, perform a


simple operation, and then remove the semaphore set.
► int main() {

► key_t key = ftok("semfile", 65); // Generate a unique key

► int semid = semget(key, 1, 0666 | IPC_CREAT); // Create a semaphore set with one semaphore

► if (semid == -1) {

► perror("semget");

► exit(1);

► }

► struct sembuf sem_op; // Perform a wait (P) operation: decrement the semaphore by 1

► sem_op.sem_num = 0; // Semaphore number

► sem_op.sem_op = -1; // Decrement by 1

► sem_op.sem_flg = 0; // No special flags

► if (semop(semid, &sem_op, 1) == -1) {

► perror("semop");

► exit(1);

► }

► printf("Semaphore decremented\n"); // Perform a signal (V) operation: increment the semaphore by 1

► sem_op.sem_op = 1; // Increment by 1

► if (semop(semid, &sem_op, 1) == -1) {

► perror("semop");

► exit(1);

► }

► printf("Semaphore incremented\n");

► // Remove the semaphore set

► if (semctl(semid, 0, IPC_RMID) == -1) {

► perror("semctl");

► exit(1);

► }

► printf("Semaphore set removed\n");

► return 0;

► }
Removing a Semaphore Set

► Use ‘semctl()’ function with the ‘IPC_RMID’ command


► #include <sys/types.h>
► #include <sys/ipc.h>
► #include <sys/sem.h>
► int semctl(int semid, int semnum, int cmd, ...);
► By understanding how to create, manipulate, and remove semaphores, you
can effectively manage inter-process synchronization in our applications.
► To create a semaphore we need System V IPC key
► The file should exist and it should be accessible.
► ftok() returns a System V IPC Key
► Semget gets a set of semaphores associated with first argument key.
► It is notable that you will get not one but a set of semaphores with semget
file locking with semaphores

► File locking using semaphores in System V IPC (Inter-Process Communication)


in Unix involves using semaphores to coordinate access to a shared resource,
such as a file, among multiple processes.
1. Creating and Initializing the Semaphore

► First, you need to create a semaphore using the ‘semget’ system call. This
semaphore will be used to control access to the shared file.
► #include <sys/sem.h>
► #include <sys/types.h>
► #include <sys/ipc.h>
► #include <stdio.h>
► #include <stdlib.h>
► #define SEM_KEY 1234 // Example semaphore key
► #define SEM_PERMS 0666 // Permissions for semaphore
► int semaphore_id;
► void init_semaphore() {
► semaphore_id = semget(SEM_KEY, 1, IPC_CREAT | SEM_PERMS);
► if (semaphore_id == -1) {
► perror("Failed to create semaphore");
► exit(1);
► }
► }
► void set_semaphore_value(int value) {
► union semun {
► int val;
► struct semid_ds *buf;
► unsigned short *array;
► } semarg;

► semarg.val = value;
► if (semctl(semaphore_id, 0, SETVAL, semarg) == -1) {
► perror("Failed to set semaphore value");
► exit(1);
► }
► }
2. Locking the File

To lock the file using the semaphore, you typically decrease (P operation) the semaphore value.
This indicates that the file is in use and prevents other processes from accessing it concurrently.
c
► void semaphore_lock() {
► struct sembuf sem_op;

► sem_op.sem_num = 0;
► sem_op.sem_op = -1; // P operation (decrement)
► sem_op.sem_flg = SEM_UNDO;

► if (semop(semaphore_id, &sem_op, 1) == -1) {


► perror("Failed to lock semaphore");
► exit(1);
► }
► }
Unlocking the File

► To unlock the file, you increase (V operation) the semaphore value, allowing
other processes to access the file.
► void semaphore_unlock() {
► struct sembuf sem_op;

► sem_op.sem_num = 0;
► sem_op.sem_op = 1; // V operation (increment)
► sem_op.sem_flg = SEM_UNDO;

► if (semop(semaphore_id, &sem_op, 1) == -1) {


► perror("Failed to unlock semaphore");
► exit(1);
► }
► }
Shared Memory
Shared Memory

► It is a mechanism that allows multiple processes to access a common memory


segment.
► This method is highly efficient for data exchange between processes.
Shared Memory Segments:

• A portion of physical memory that can be accessed by multiple processes.


• Identified by a unique identifier called a ‘shmid’.
Shared memory is not part of process A or B
System Calls:

•shmget(): Allocates a shared memory segment.\

•shmat(): Attaches the shared memory segment to the process's address space.

•shmdt(): Detaches the shared memory segment from the process's address space.

•shmctl(): Controls operations on the shared memory segment, like marking it for deletion.
Using the Shared Memory:
Creating a Shared Memory Segment:

int shmget(key_t key, size_t size, int shmflg);


Attaching the Shared Memory
Segment:

void* shmat(int shmid, const void *shmaddr, int shmflg);


attach
Using the Shared Memory:

► Once attached, the shared memory can be accessed like any other part of the
process's memory.
Detaching the Shared Memory
Segment:

int shmdt(const void *shmaddr);


Use shmdt to detach the shared memory segment.
shmaddr the address of the attached shared memory segment.
Controlling the Shared Memory
Segment:

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

You might also like