0% found this document useful (0 votes)
6 views8 pages

Distributed Practical

The document contains implementations of Remote Procedure Call (RPC) and Remote Method Invocation (RMI) in Python, including server-client communication for addition and subtraction operations. It also includes simulations for Lamport Logical Clocks, Mutual Exclusion, and Deadlock Detection using various algorithms. The code snippets demonstrate threading, socket programming, and user input handling for interactive operations.

Uploaded by

nnitishvarshney
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)
6 views8 pages

Distributed Practical

The document contains implementations of Remote Procedure Call (RPC) and Remote Method Invocation (RMI) in Python, including server-client communication for addition and subtraction operations. It also includes simulations for Lamport Logical Clocks, Mutual Exclusion, and Deadlock Detection using various algorithms. The code snippets demonstrate threading, socket programming, and user input handling for interactive operations.

Uploaded by

nnitishvarshney
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

4/10/26, 1:26 PM Untitled13.

ipynb - Colab

keyboard_arrow_down [Link] of RPC

from [Link] import SimpleXMLRPCServer


import [Link]
import threading
import time

# ------------------ SERVER PART ------------------


def add(a, b):
return a + b

def subtract(a, b):


return a - b

def start_server():
server = SimpleXMLRPCServer(("localhost", 8000))
print("Server started on port 8000...")

server.register_function(add, "add")
server.register_function(subtract, "subtract")

server.serve_forever()

# Run server in separate thread


server_thread = [Link](target=start_server)
server_thread.daemon = True
server_thread.start()

# Give server time to start


[Link](1)

# ------------------ CLIENT PART ------------------


client = [Link]("[Link]

print("Addition:", [Link](10, 5))


print("Subtraction:", [Link](20, 8))

Exception in thread Thread-5 (start_server):


Traceback (most recent call last):
File "/usr/lib/python3.12/[Link]", line 1075, in _bootstrap_inner
[Link]()
File "/usr/lib/python3.12/[Link]", line 1012, in run
self._target(*self._args, **self._kwargs)
File "/tmp/ipykernel_3675/[Link]", line 14, in start_server
File "/usr/lib/python3.12/xmlrpc/[Link]", line 594, in __init__
[Link].__init__(self, addr, requestHandler, bind_and_activate)
File "/usr/lib/python3.12/[Link]", line 457, in __init__
self.server_bind()
File "/usr/lib/python3.12/[Link]", line 478, in server_bind
[Link](self.server_address)
OSError: [Errno 98] Address already in use
Addition: 15
Subtraction: 12
[Link] - - [10/Apr/2026 07:52:07] "POST / HTTP/1.1" 200 -
[Link] - - [10/Apr/2026 07:52:07] "POST / HTTP/1.1" 200 -

keyboard_arrow_down [Link] of RPC by taking user data

from [Link] import SimpleXMLRPCServer


import [Link]
import threading
import time

# ------------------ SERVER PART ------------------


def add(a, b):
return a + b

def subtract(a, b):


return a - b
[Link] 1/8
4/10/26, 1:26 PM [Link] - Colab

def start_server():
server = SimpleXMLRPCServer(("localhost", 8000))
print("Server started on port 8000...")

server.register_function(add, "add")
server.register_function(subtract, "subtract")

server.serve_forever()

# Run server in separate thread


server_thread = [Link](target=start_server)
server_thread.daemon = True
server_thread.start()

# Give server time to start


[Link](1)

# ------------------ CLIENT PART ------------------


client = [Link]("[Link]

# Get user input for addition


print("\n--- Addition ---")
num1_add = int(input("Enter the first number for addition: "))
num2_add = int(input("Enter the second number for addition: "))
print("Addition result:", [Link](num1_add, num2_add))

# Get user input for subtraction


print("\n--- Subtraction ---")
num1_sub = int(input("Enter the first number for subtraction: "))
num2_sub = int(input("Enter the second number for subtraction: "))
print("Subtraction result:", [Link](num1_sub, num2_sub))

Exception in thread Thread-6 (start_server):


Traceback (most recent call last):
File "/usr/lib/python3.12/[Link]", line 1075, in _bootstrap_inner
[Link]()
File "/usr/lib/python3.12/[Link]", line 1012, in run
self._target(*self._args, **self._kwargs)
File "/tmp/ipykernel_3675/[Link]", line 14, in start_server
File "/usr/lib/python3.12/xmlrpc/[Link]", line 594, in __init__
[Link].__init__(self, addr, requestHandler, bind_and_activate)
File "/usr/lib/python3.12/[Link]", line 457, in __init__
self.server_bind()
File "/usr/lib/python3.12/[Link]", line 478, in server_bind
[Link](self.server_address)
OSError: [Errno 98] Address already in use

--- Addition ---


Enter the first number for addition: 6
Enter the second number for addition: 5
[Link] - - [10/Apr/2026 07:52:15] "POST / HTTP/1.1" 200 -
Addition result: 11

--- Subtraction ---


Enter the first number for subtraction: 6
Enter the second number for subtraction: 2
Subtraction result: 4
[Link] - - [10/Apr/2026 07:52:20] "POST / HTTP/1.1" 200 -

keyboard_arrow_down [Link] of RMI

import socket
import threading
import json

# ---------- SERVER PART ----------


def handle_client(conn, addr):
print(f"Connected by {addr}")
data = [Link](1024).decode()

if not data:
return

request = [Link](data)

[Link] 2/8
4/10/26, 1:26 PM [Link] - Colab
method = [Link]("method")
params = [Link]("params", [])

# Remote methods
def add(a, b):
return a + b

def subtract(a, b):


return a - b

# Method dispatcher
if method == "add":
result = add(*params)
elif method == "subtract":
result = subtract(*params)
else:
result = "Method not found"

response = [Link]({"result": result})


[Link]([Link]())
[Link]()

def start_server():
server = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](("localhost", 5000))
[Link](5)

print("RMI Server running on port 5000...")

while True:
conn, addr = [Link]()
[Link](target=handle_client, args=(conn, addr)).start()

# ---------- CLIENT PART ----------


def call_remote_method(method, params):
client = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](("localhost", 5000))

request = [Link]({
"method": method,
"params": params
})

[Link]([Link]())

response = [Link](1024).decode()
result = [Link](response)

[Link]()
return result["result"]

# ---------- MAIN ----------


if __name__ == "__main__":
import time

# Start server in background


[Link](target=start_server, daemon=True).start()

[Link](1) # Give server time to start

# Client calls
print("Calling remote add(5, 3)...")
print("Result:", call_remote_method("add", [5, 3]))

print("Calling remote subtract(10, 4)...")


print("Result:", call_remote_method("subtract", [10, 4]))

RMI Server running on port 5000...


Calling remote add(5, 3)...
Connected by ('[Link]', 54930)
Result: 8
Calling remote subtract(10, 4)...
Connected by ('[Link]', 54944)
Result: 6

[Link] 3/8
4/10/26, 1:26 PM [Link] - Colab

keyboard_arrow_down [Link] of RMI by taking user data

import socket
import threading
import json

# ---------- SERVER PART ----------


def handle_client(conn, addr):
print(f"Connected by {addr}")
data = [Link](1024).decode()

if not data:
return

request = [Link](data)

method = [Link]("method")
params = [Link]("params", [])

# Remote methods
def add(a, b):
return a + b

def subtract(a, b):


return a - b

# Method dispatcher
if method == "add":
result = add(*params)
elif method == "subtract":
result = subtract(*params)
else:
result = "Method not found"

response = [Link]({"result": result})


[Link]([Link]())
[Link]()

def start_server():
server = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](("localhost", 5000))
[Link](5)

print("RMI Server running on port 5000...")

while True:
conn, addr = [Link]()
[Link](target=handle_client, args=(conn, addr)).start()

# ---------- CLIENT PART ----------


def call_remote_method(method, params):
client = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](("localhost", 5000))

request = [Link]({
"method": method,
"params": params
})

[Link]([Link]())

response = [Link](1024).decode()
result = [Link](response)

[Link]()
return result["result"]

# ---------- MAIN ----------


if __name__ == "__main__":
import time

[Link] 4/8
4/10/26, 1:26 PM [Link] - Colab

# Start server in background


[Link](target=start_server, daemon=True).start()

[Link](1) # Give server time to start

# Client calls with user input


print("\n--- RMI Addition ---")
num1_add = int(input("Enter the first number for RMI addition: "))
num2_add = int(input("Enter the second number for RMI addition: "))
print("Result of RMI addition:", call_remote_method("add", [num1_add, num2_add]))

print("\n--- RMI Subtraction ---")


num1_sub = int(input("Enter the first number for RMI subtraction: "))
num2_sub = int(input("Enter the second number for RMI subtraction: "))
print("Result of RMI subtraction:", call_remote_method("subtract", [num1_sub, num2_sub]))

Exception in thread Thread-10 (start_server):


Traceback (most recent call last):
File "/usr/lib/python3.12/[Link]", line 1075, in _bootstrap_inner
[Link]()
File "/usr/lib/python3.12/[Link]", line 1012, in run
self._target(*self._args, **self._kwargs)
File "/tmp/ipykernel_3675/[Link]", line 40, in start_server
OSError: [Errno 98] Address already in use

--- RMI Addition ---


Enter the first number for RMI addition: 7
Enter the second number for RMI addition: 4
Connected by ('[Link]', 54958)
Result of RMI addition: 11

--- RMI Subtraction ---


Enter the first number for RMI subtraction: 8
Enter the second number for RMI subtraction: 2
Connected by ('[Link]', 57668)
Result of RMI subtraction: 6

keyboard_arrow_down [Link] of Lamport Logical Clocks

p1 = 0
p2 = 0
p3 = 0

p1 += 1
p1 += 1
print("P1 sends message to P2 at time", p1)

p2 = max(p2, p1) + 1
print("P2 receives message at time", p2)

p2 += 1
print("P2 sends message to P3 at time", p2)

p3 = max(p3, p2) + 1
print("P3 receives message at time", p3)

P1 sends message to P2 at time 2


P2 receives message at time 3
P2 sends message to P3 at time 4
P3 receives message at time 5

keyboard_arrow_down [Link] of Mutual Exclusion

N = 3
for i in range(N):
print("Process", i, "sending REQUEST to other processes")

replies = int(input("Enter number of REPLY received: "))

if replies == N-1:
print("Process", i, "ENTERING Critical Section")
print("Process", i, "EXITING Critical Section\n")

[Link] 5/8
4/10/26, 1:26 PM [Link] - Colab

else:
print("Process", i, "WAITING (Some process did not reply)\n")

Process 0 sending REQUEST to other processes


Enter number of REPLY received: 3
Process 0 WAITING (Some process did not reply)

Process 1 sending REQUEST to other processes


Enter number of REPLY received: 2
Process 1 ENTERING Critical Section
Process 1 EXITING Critical Section

Process 2 sending REQUEST to other processes


Enter number of REPLY received: 5
Process 2 WAITING (Some process did not reply)

keyboard_arrow_down [Link] Detection

import collections

# A simplified representation of a distributed wait-for graph


# Each key (process_id) waits for the process_id in its value list.
# For example: wait_for_graph = {"P1": ["P2"], "P2": ["P3"], "P3": ["P1"]} would represent a deadlock.

def detect_deadlock(wait_for_graph):
"""
Detects deadlocks in a wait-for graph using Depth First Search (DFS).
A cycle in the wait-for graph indicates a deadlock.
Returns True if a deadlock is detected, along with a list of processes
involved in the detected cycle, otherwise False and an empty list.
"""
visited = set()
recursion_stack = [Link]() # To store the current path in DFS

def dfs(process):
[Link](process)
recursion_stack.append(process)

for neighbor in wait_for_graph.get(process, []):


if neighbor not in visited:
cycle = dfs(neighbor)
if cycle:
return cycle
elif neighbor in recursion_stack:
# Cycle detected! Reconstruct the cycle.
# The cycle starts from 'neighbor' and goes through processes
# currently in the recursion_stack until 'process'.
cycle_start_index = list(recursion_stack).index(neighbor)
return list(recursion_stack)[cycle_start_index:] + [neighbor]

recursion_stack.pop() # Backtrack
return None

for process in wait_for_graph:


if process not in visited:
cycle = dfs(process)
if cycle:
return True, cycle
return False, []

# --- Example Usage ---

print("--- Distributed Deadlock Detection Simulation ---")

# Scenario 1: No Deadlock
print("\nScenario 1: No Deadlock")
wait_for_graph_no_deadlock = {
"P1": ["P2"],
"P2": ["P3"],
"P3": []
}
print("Wait-for graph:", wait_for_graph_no_deadlock)
deadlock_detected, cycle = detect_deadlock(wait_for_graph_no_deadlock)

[Link] 6/8
4/10/26, 1:26 PM [Link] - Colab
if deadlock_detected:
print("Deadlock detected! Processes involved in cycle:", cycle)
else:
print("No deadlock detected.")

# Scenario 2: Deadlock Detected (P1 -> P2 -> P3 -> P1)


print("\nScenario 2: Deadlock Detected (P1 -> P2 -> P3 -> P1)")
wait_for_graph_deadlock = {
"P1": ["P2"],
"P2": ["P3"],
"P3": ["P1"]
}
print("Wait-for graph:", wait_for_graph_deadlock)
deadlock_detected, cycle = detect_deadlock(wait_for_graph_deadlock)
if deadlock_detected:
print("Deadlock detected! Processes involved in cycle:", cycle)
else:
print("No deadlock detected.")

# Scenario 3: Another Deadlock (more complex: P_A -> P_B -> P_C -> P_A)
print("\nScenario 3: Another Deadlock Detected (P_A -> P_B -> P_C -> P_A)")
wait_for_graph_deadlock_2 = {
"P_A": ["P_B"],
"P_B": ["P_C"],
"P_C": ["P_A", "P_D"], # P_C waits for P_A, creating a cycle
"P_D": []
}
print("Wait-for graph:", wait_for_graph_deadlock_2)
deadlock_detected, cycle = detect_deadlock(wait_for_graph_deadlock_2)
if deadlock_detected:
print("Deadlock detected! Processes involved in cycle:", cycle)
else:
print("No deadlock detected.")

# Scenario 4: No Deadlock with multiple paths


print("\nScenario 4: No Deadlock with multiple paths")
wait_for_graph_no_deadlock_2 = {
"P_X": ["P_Y", "P_Z"],
"P_Y": [],
"P_Z": ["P_W"],
"P_W": []
}
print("Wait-for graph:", wait_for_graph_no_deadlock_2)
deadlock_detected, cycle = detect_deadlock(wait_for_graph_no_deadlock_2)
if deadlock_detected:
print("Deadlock detected! Processes involved in cycle:", cycle)
else:
print("No deadlock detected.")

--- Distributed Deadlock Detection Simulation ---

Scenario 1: No Deadlock
Wait-for graph: {'P1': ['P2'], 'P2': ['P3'], 'P3': []}
No deadlock detected.

Scenario 2: Deadlock Detected (P1 -> P2 -> P3 -> P1)


Wait-for graph: {'P1': ['P2'], 'P2': ['P3'], 'P3': ['P1']}
Deadlock detected! Processes involved in cycle: ['P1', 'P2', 'P3', 'P1']

Scenario 3: Another Deadlock Detected (P_A -> P_B -> P_C -> P_A)
Wait-for graph: {'P_A': ['P_B'], 'P_B': ['P_C'], 'P_C': ['P_A', 'P_D'], 'P_D': []}
Deadlock detected! Processes involved in cycle: ['P_A', 'P_B', 'P_C', 'P_A']

Scenario 4: No Deadlock with multiple paths


Wait-for graph: {'P_X': ['P_Y', 'P_Z'], 'P_Y': [], 'P_Z': ['P_W'], 'P_W': []}
No deadlock detected.

keyboard_arrow_down [Link] Testing

while True:
new_text = input("Enter a news article (or 'exit' to quit): ")

vac = [Link]([new_text])

prediction = [Link](vac)

[Link] 7/8
4/10/26, 1:26 PM [Link] - Colab
print("prediction model", [Link](vac))

Enter a news article (or 'exit' to quit):

[Link] 8/8

You might also like