What is multiprocesing? Discuss different types of data transfer in detail.


Q.) What is multiprocesing? Discuss different types of data transfer in detail.

Subject: Computer Organization and Architecture

What is Multiprocessing?

Multiprocessing refers to the ability of a system to support more than one processor at the same time. Applications in a multiprocessing system are broken down into smaller routines that run independently. The operating system allocates these threads to the processors improving performance and efficiency.

In the context of computer programming, multiprocessing usually refers to the use of multiple processes (which may or may not be running on separate CPUs) to perform tasks concurrently. Each process runs in its own memory space, and if they need to communicate or share data, they must do so using inter-process communication (IPC) mechanisms.

Types of Data Transfer in Multiprocessing

When dealing with multiprocessing, data transfer between processes is a critical aspect. There are several methods for IPC, each with its own use cases and advantages. Here are some of the most common types:

Method Description Use Cases Advantages Disadvantages
Pipes Pipes are one of the simplest forms of IPC. They allow for unidirectional communication between two processes. Simple data streaming from one process to another. Easy to use and implement. Unidirectional, not suitable for complex data structures.
Named Pipes (FIFOs) Named pipes are similar to regular pipes but they are accessed as part of the file system, which means they can be used between unrelated processes and persist beyond the life of the processes. Inter-process communication when processes are not related or do not have a parent-child relationship. Bidirectional communication, more flexible than unnamed pipes. More complex to implement, can be slower than memory-based IPC.
Message Queues Message queues allow processes to communicate by sending messages to each other. This is a more advanced form of IPC which can handle complex data structures and provides a way to queue messages. Complex data transfer where messages need to be selected or processed in specific orders. Can prioritize messages, robust against system crashes. More overhead than pipes, can be complex to implement.
Shared Memory Shared memory allows multiple processes to access the same memory space. It's a very efficient way of sharing data because it doesn't involve copying data between processes. High-performance applications where speed is critical. Very fast, as there's no data copying. Requires synchronization to prevent race conditions, can be complex to implement correctly.
Sockets Sockets provide a way for processes to communicate over a network. They can be used for both local IPC and communicating over the internet. Networked applications, distributed systems. Flexible, can be used for both local and remote communication. More overhead than local IPC methods, can be complex to implement.
Semaphores Semaphores are not a direct method of IPC for data transfer but are used to control access to shared resources like shared memory. Synchronizing access to shared resources. Provides a way to avoid race conditions. Does not transfer data itself, can lead to deadlocks if not used carefully.

Examples

Pipes

int fds[2];
pipe(fds);
if (fork() == 0) {
    // Child process
    close(fds[1]); // Close unused write end
    char readbuffer[80];
    read(fds[0], readbuffer, sizeof(readbuffer));
    printf("Received string: %s\n", readbuffer);
    close(fds[0]);
} else {
    // Parent process
    close(fds[0]); // Close unused read end
    write(fds[1], "Hello, child!", 13);
    close(fds[1]);
}

Shared Memory

#include 
#include 

// Parent process
int shm_fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, sizeof(int));
int *counter = mmap(0, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
*counter = 0;

if (fork() == 0) {
    // Child process
    (*counter)++;
    munmap(counter, sizeof(int));
    close(shm_fd);
} else {
    // Parent process
    wait(NULL); // Wait for child to finish
    printf("Counter value is %d\n", *counter);
    munmap(counter, sizeof(int));
    close(shm_fd);
    shm_unlink("/my_shm");
}

Message Queues

#include 
#include 

struct my_msgbuf {
    long mtype;
    char mtext[200];
};

int main(void) {
    struct my_msgbuf buf;
    int msqid;
    key_t key;

    key = ftok("somefile", 'b');
    msqid = msgget(key, 0644 | IPC_CREAT);

    buf.mtype = 1; /* We need to send the type of message */
    strcpy(buf.mtext, "Hello, world!");

    msgsnd(msqid, &buf, sizeof(buf.mtext), 0);

    // Receiving message
    msgrcv(msqid, &buf, sizeof(buf.mtext), 1, 0);
    printf("%s\n", buf.mtext);

    return 0;
}

In these examples, we see how different IPC mechanisms can be used for data transfer in multiprocessing environments. Each method has its own syntax and semantics, but they all serve the purpose of allowing processes to communicate and coordinate their actions.