3.4 Interprocess Communication

Processes executing concurrently may be either independent processes or cooperating processes.

A process is independent if it does not share data with any other processes.

A process is cooperating if it can affect or be affected by the other processes. Clearly, any processes that shares data with other processes is a cooperating process.

IPC: Inter-process Communication

Cooperating processes require an IPC mechanism that will allow them to exchange data that is, send data to and receive data from each other.

Two fundamental models of IPC:

  1. shared memory

  2. message passing

3.5 IPC in Shared-Memory Systems

Consider the Producer-Consumer Problem to illustrate the concept of cooperating processes. Producer-Consumer Problem is a common paradigm for cooperating processes.

Producer-Consumer Problem

A producer produces information that is consumed by a consumer.

For example

  • a compiler produces assembly code, and a assembler consumes it.

  • a web server produces an HTML, file, and a browser consums it.

A solution using shared-memory to allow producer and consumer to run concurrently.

Let a buffer of items be available

  • a producer can fill the buffer

  • a consumer can empty the buffer

A shared memory is a region of memory shared by the producer and consumer processes.

Define a shared buffer

#define BUFFER_SIZE 10

typedef struct {
	...
} item;

item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;

// The producer process using shared memory
item next_produced;

while (true) {
	/* produce an item in next_produced */
    
    while (((in + 1) % BUFFER_SIZE) == out)
    	; /* do nothing */
        // waiting
	
    buffer[in] = next_produced;
    in = (in + 1) % BUFFER_SIZE;
}

// The consumer process using shared memory

while (true) {
	while (in == out)
		; /* do nothing */

	next_consumed = buffer[out];
    out = (out + 1) % BUFFER_SIZE;
    
    /* consume the item in next_consumed */
}

3.6 IPC in Message-Passing Systems

The scheme of using shared-memory

  • requires that these processes share a region of memory and that

  • the code for accessing and manipulating the shared memory be written explicitly by the application programmer.

Message-Passing

O/S provides the means for cooperating processes to communicate with each other via a message-passing facility.

Two operations of the message-passing facility

  1. send(message)

  2. receive(message)

// The producer process using message passing

message next_produced;

while (true) {
	/* produce an item in next_produced */
    
    send(next_produced);
}

// The consumer process using message passing

message next_consumed;

while (true) {
	receive(next_consumed);
    
    /* consume the item in next_consumed */
}

if two processes &&P&& and &&Q&& want to communicate, they must send to and receive messages from each other.

This communication link can be implemented in a variety of ways

  • direct or indirect communication

  • synchronous and asynchronous communication

  • automatic or explicit buffering

Under direct communication

each process that wants to communicate must explicitly name the recipient or sender of the communication.

The primitives of this scheme:

send(PP, message) - send a message to process PP.
receive(QQ, message) - receive a message from process QQ.

The properties of communication links in this scheme

Links are established automatically.
A link is associcated with exactly two processes.
There exists exactly one link between each pair of processes.

With indirect communication

the messages are sent to and received from ports(, or mailboxes.)

A mailbox (also referred to as ports)

  • can be viewed abstractly as an object

  • into wich messages can be placed by processes, and

  • from which messages can be removed.

The primitives of this scheme:

send(AA, message) - send a message to mailbox AA.
receive(AA, message) - receive a message from mailbox AA.

The properties of communication links in this scheme

Links are established between a pair of processes only if both members of the pair have shared mailbox.
A link may be associcated with more than two processes.
A number of different links may exist, between each pair of processes with each link corresponding to one mailbox.

OS provides a mechanism that allows a process to do

  1. Create a new mailbox.

  2. Send and Receive messages through the mailbox.

  3. Delete a mailbox.

Different design options for implementation

blocking : non-blocking = synchronous : asynchronous

  • Blocking send: the sender is blocked until the message is received.

  • Non-blocking send: the sender is sends the message and

  • Blocking receive: the receiver blocks until a message is

  • Non-blocking receive: the receiver retrieves either a valid message or
    a null message.

3.7 Examples of IPC Systems

  1. Shared Memory: POSIX Shared Memory

    • POSIX: Portable Operating System Interface (for UNIX)

    • tried to standardization (but failed)

  2. Message Passing: Pipes

    • One of the earliest IPC mechanisms on UNIX systems.

POSIX Shared Memory

is organized using memory mapped files, which associate the region of shared memory with a file. (for speed)

  1. First, create a shared memory object
    fd = shm_open(name, O_CREAT | ORDWR, 0666);

  2. Configure the size of the object in bytes
    ftruncate(fd, 4096);
    4096: unit of reading & writing

  3. Finally, establish a memory mapped file
    mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

Producer process illustrating POSIX shared-memory API

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main()
{
	const int SIZE = 4096; // the size of shared memory
	const char *name = "OS"; // the name of shared memory
	const char *message_0 = "Hello, ";
    const char *message_1 = "Shared Memory! \n";

	int shm_fd; // the file descriptor of shared memory
    char *ptr; // pointer to shared memory

	/* create the shared memory object */
	shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);

	/* configure the size of the shared memory */
    ftruncate (shm_fd, SIZE);

	/* map the shared memory object */
	ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);

	/* write to the shared memory */
    sprintf(ptr, "%s", message_0);
    ptr += strlen(message_0); // moving pointer
    sprintf(ptr, "%s", message_1);
    ptr += strlen(message_1); // moving pointer

	return 0;
}

Compile

$ gcc 3.16_shm_producer.c -lrt

Consumer process illustrating POSIX shared-memory API

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main()
{
	const int SIZE = 4096; // the size of shared memory
    const char *name = "OS"; // the name of shared memory
    
    int shm_fd; // the file descriptor of shared memory
    char *ptr; // pointer to shared memory

	/* create the shared memory object */
	shm_fd = shm_open(name, O_RDONLY, 0666);

	/* map the shared memory object */
	ptr = (char *)mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);

	/* read from the shared memory object */
	printf("%s", (char *)ptr);
    
    /* remove the shared memory */
    shm_unlink(name);

	return 0;
}

Compile

$ gcc 3.16_shm_consumer.c -lrt

Pipes

were one of the first IPC mechanisms in early UNIX systems.

A pipe acts as a conduit allowing two processes to communicate.

Four issues of pipe implementation:

  1. Does the pipe allow unidirectional or bidirectional communication?

  2. In the case of two way comm., is it half-duplex or full-duplex?

  3. Must a relationship exist between the communicating process, such as parent child?

  4. Can the pipes communicate over a network?

Two common types of pipes
1. Ordinary pipes
cannot be accessed from outside the process that created it. Typically, a parent process creates a pipe and uses it to communicate with a child process that it created.
2. Named pipes
can be accessed without a parent-child relationship.

Ordinary pipes

allow two processes to communicate in producer-consumer fashion.

  • the producer writes to one end of the pipe (write end)

  • the consumger reads from the other end (read end)

unidirectional: only one-way communication is possible.

  • If you want two-way communication, then use two pipes.

On UNIX systems

  • ordinary pipes are constructed using the function

    pipe(int fd[])
    fd[0]: the read end of the pipe
    fd[1]: the write end

Ordinary pipe in UNIX

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1

int main()
{
	char write_msg[BUFFER_SIZE] = "Greetings";
	char read_msg[BUFFER_SIZE];
	int fd[2];
	pid_t pid;
	
    /* create the pipe */
	pipe(fd);
    
	pid = fork(); // fork a new process

	if (pid > 0) { // parent process
		close(fd[READ_END]);
		/* write to the pipe */
		write(fd[WRITE_END], write_msg, strlen(write_msg) + 1);
        close(fd[WRITE_END]);
	}
    else if (pid == 0) { // child process
		close(fd[WRITE_END]);
		/* read to the pipe */
		read(fd[READ_END], read_msg, BUFFER_SIZE);
		printf("read %s\n", read_msg);
		close(fd [READ_END]);
	}

    return 0;
}

3.8 Communication in Client-Server System

Two other strategies in client-server (not locally) systems

  1. Sockets are defined as endpoints for communication.

  2. RPCs(Remote Procedure Calls) abstracts procedure calls between processes on networked systems.

Socket

identified by and IP address concatenated with a port number.

Java

provides a much easier interface to sockets

Java provides three different types of sockets
1. Socket class: connection-oriented (TCP)
2. DatagramSocket class: connectionless (UDP)

broadcasting to everyone
  1. MulticastSocket class: multiple recipients
broadcasting to someone

Date server in Java

Date client in Java

RPC(Remote Procedure Call)

  • is one of the most common forms of remote service.

  • designed as a way to abstract the procedure call mechanism for use between systems with network connections.

  • A client invokes a procedure on a remote host as it would invoke a procedure locally.

The RPC system

hides the details that allow communication to take place by providing a stub on the client side.

The stub of client-side locates the server and marshals the parameters.

The stub of server-side received this message,

  • unpacks the marshalled parameters, and

  • performs the procedure on the server.

profile
열심히 살겠습니다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN