Simulates Java Remote Method Invocation (RMI) using Python's built-in
xmlrpc module. A custom threaded server spawns a new thread for each client
connection, allowing multiple clients to invoke remote calculator methods concurrently.
Five client threads run in parallel, each calling add, subtract,
multiply, divide, and echo on the same server.
| File | Role |
|---|---|
| server.py | Threaded XML-RPC server — registers RemoteCalculator and handles each client in its own thread |
| client.py | Spawns 5 concurrent client threads, each invoking all remote methods via ServerProxy |
# Python 3.8+ required (xmlrpc is in the standard library) winget install Python.Python.3.11 # or download from python.org # No extra pip packages needed
sudo apt update && sudo apt install python3 python3-pip # No extra pip packages needed
Get the files with dsnip get p1 — they appear in ./ds_code/p1/.
dsnip get p1 cd ds_code\p1
dsnip get p1 cd ds_code/p1
Open Terminal 1 and start the server.
python server.py
python3 server.py
Open Terminal 2 and run the multi-threaded client.
python client.py
python3 client.py
Press Ctrl+C in Terminal 1 to stop the server.
[Client-1] Connected to RMI server at http://localhost:8000 [Client-1] add(10, 5) = 15 [Client-2] subtract(100, 6) = 94 [Client-3] multiply(3, 7) = 21 [Client-4] divide(100, 4) = 25.00 [Client-5] echo → 'Server echoes: Hello from client 5' [Main] All client threads finished.
Simulates CORBA (Common Object Request Broker Architecture) using
Pyro5 (Python Remote Objects). A Name Server acts as the broker
(CosNaming), the server registers a CalculatorServant object with it, and the
client resolves the logical name corba.calculator to get a transparent proxy
(stub). All method calls cross the network with full location transparency.
| File | Role |
|---|---|
| server.py | Servant object — registers CalculatorServant with the Name Server as corba.calculator |
| client.py | Stub/proxy client — resolves the name, creates a Pyro5 proxy, invokes arithmetic and string methods |
winget install Python.Python.3.11 pip install Pyro5
sudo apt install python3 python3-pip pip3 install Pyro5
Get the files.
dsnip get p2 cd ds_code\p2
dsnip get p2 cd ds_code/p2
Terminal 1 — Start the Pyro5 Name Server (broker).
python -m Pyro5.nameserver
python3 -m Pyro5.nameserver
Terminal 2 — Start the Calculator Servant.
python server.py
python3 server.py
Terminal 3 — Run the client.
python client.py
python3 client.py
[ORB] Name Server located.
[ORB] Resolved 'corba.calculator' → PYRO:obj_...
[Client] Proxy (stub) created
── Arithmetic Operations ──
add(15, 7) = 22
multiply(6, 9) = 54
power(2, 10) = 1024.0
── String Operations ──
string_reverse('CORBA') = ABROC
── Error Handling Demo ──
divide(10, 0) raised: ValueError: Division by zero
Simulates MPI-style distributed computation using Python's
multiprocessing module. An array of N elements is divided into
N/n chunks and distributed to n worker processes (MPI ranks). Each worker
computes a partial (intermediate) sum of its chunk, and the master
gathers and adds them to produce the final sum.
| File | Role |
|---|---|
| distributed_sum.py | Master + worker processes — implements scatter, parallel summation, and gather phases |
winget install Python.Python.3.11 # No extra packages — uses built-in multiprocessing
sudo apt install python3 # No extra packages
dsnip get p3 cd ds_code\p3 python distributed_sum.py
dsnip get p3 cd ds_code/p3 python3 distributed_sum.py
To customize, edit the bottom of distributed_sum.py:
distributed_sum(N=20, num_processors=4) # random array distributed_sum(N=15, num_processors=3, array=[...]) # custom array
Total elements (N) : 20 Number of processors (n) : 4 Elements per processor (N/n) : ~5 [Processor-0] Assigned elements : [12, 45, 3, 67, 8] [Processor-0] Intermediate sum : 135 [Processor-1] Intermediate sum : 193 ... Final Distributed Sum = 947 Direct Sum (verify) = 947 Match: [OK] CORRECT
Implements the Berkeley Algorithm — a master-slave clock synchronization protocol that does not rely on an external time source (unlike NTP). The master polls all slave clocks, computes the average time, calculates a per-node adjustment delta, and broadcasts corrections. All clocks converge to a synchronized average.
| File | Role |
|---|---|
| berkeley_clock_sync.py | Complete simulation — ClockNode with skew, BerkeleyMaster that polls, averages, and sends deltas |
winget install Python.Python.3.11 # No extra packages
sudo apt install python3 # No extra packages
dsnip get p4 cd ds_code\p4 python berkeley_clock_sync.py
dsnip get p4 && cd ds_code/p4 python3 berkeley_clock_sync.py
--- Before Synchronization --- Master skew=+2.341s local_time=... Slave-1 skew=-7.823s local_time=... Clock spread before sync : 14.2310 seconds Step 1: Master polls all slave clocks Step 2: Master computes average time = ... Step 3: Master sends adjustment deltas Master adjustment: +1.2300s Slave-1 adjustment: -2.1100s --- After Synchronization --- Clock spread after sync : 0.000001 seconds Improvement : 14231.0x reduction in skew [OK] Berkeley synchronization complete.
Implements the Token Ring algorithm for mutual exclusion using Python threads. Processes are arranged in a logical ring (P0→P1→…→Pn→P0). A single TOKEN circulates; only the token-holder may enter its Critical Section (CS). Guarantees: mutual exclusion, no deadlock, no starvation, and fair round-robin access.
| File | Role |
|---|---|
| token_ring.py | RingProcess (one thread/node) + coordinator that injects the initial token and collects stats |
winget install Python.Python.3.11 # uses built-in threading + queue
sudo apt install python3 # no extra packages
dsnip get p5 cd ds_code\p5 python token_ring.py
dsnip get p5 && cd ds_code/p5 python3 token_ring.py
To change ring size or rounds, edit the last line:
run_token_ring(num_processes=5, num_rounds=3)
Ring layout: P0 -> P1 -> P2 -> P3 -> P4 -> P0 [Process-0] received TOKEN [Process-0] ENTERING Critical Section [**] [Process-0] EXITING Critical Section (CS count = 1) [Process-0] passing TOKEN -> P1 [Process-1] received TOKEN [Process-1] has no CS request - passing token immediately ... --- Simulation Summary --- Process-0: entered Critical Section 2 time(s) Mutual Exclusion : [OK] Guaranteed
Implements two classic leader election algorithms:
The coordinator crashes, a surviving process detects the failure and starts an election, and a new leader is elected via each algorithm.
| File | Role |
|---|---|
| main.py | Runner — executes Bully then Ring algorithm back-to-back |
| bully_algorithm.py | Bully election: BullyProcess + BullyElection classes |
| ring_algorithm.py | Ring election: RingElectionProcess + RingElection classes |
winget install Python.Python.3.11 # no extra packages
sudo apt install python3 # no extra packages
dsnip get p6 handles this automatically.dsnip get p6 cd ds_code\p6 python main.py
dsnip get p6 && cd ds_code/p6 python3 main.py
Run algorithms individually (optional):
python bully_algorithm.py python ring_algorithm.py
python3 bully_algorithm.py python3 ring_algorithm.py
*** PART A: BULLY ALGORITHM *** Processes: [Process-0[UP], Process-1[UP], ..., Process-5[UP]] Initial Coordinator: Process-5 -- Coordinator Process-5 CRASHES -- -- Election started by Process-2 -- Process-2 sends ELECTION to: [3, 4] -> Process-3 receives ELECTION ... OK -> Process-4 receives ELECTION ... OK [ELECTED] Process-4 declares itself COORDINATOR *** PART B: RING ALGORITHM *** Ring: P0 -> P1 -> P2 -> P3 -> P4 -> P5 -> P0 -- Coordinator Process-5 CRASHES -- -- Ring Election started by Process-2 -- -> Process-3 (higher ID, adds itself): ELECTION[2, 3] -> Process-4 (higher ID, adds itself): ELECTION[2, 3, 4] Winner (highest ID): Process-4 [OK] Ring election complete. New leader: Process-4
| Key | Practical # | Title | Files | Dependencies | Run Command |
|---|---|---|---|---|---|
| p1 | 1 | Multi-threaded RMI | server.py client.py | None (stdlib) | python server.py + python client.py |
| p2 | 2 | CORBA Object Brokering | server.py client.py | pip install Pyro5 |
3 terminals (nameserver → server → client) |
| p3 | 3 | Distributed Sum (MPI) | distributed_sum.py | None (stdlib) | python distributed_sum.py |
| p4 | 4 | Berkeley Clock Sync | berkeley_clock_sync.py | None (stdlib) | python berkeley_clock_sync.py |
| p5 | 5 | Token Ring Mutex | token_ring.py | None (stdlib) | python token_ring.py |
| p6 | 6 | Leader Election | main.py bully_algorithm.py ring_algorithm.py | None (stdlib) | python main.py |
pip install snipx-ds # install the package dsnip help # show all commands dsnip list # list all practicals dsnip list python # filter by language dsnip get p1 # copy Practical 1 files → ./ds_code/p1/ dsnip get p6 # copy Practical 6 files → ./ds_code/p6/ dsnip guide # open this guide in browser