Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Foundations: Revision Dr. Christian Vecchiola Postdoctoral Research Fellow [email protected] Cloud Computing and Distributed Systems (CLOUDS) Lab Dept. of Computer Science and Software Engineering The University of Melbourne Foundations: Revision Distributed Systems Principles and Paradigms Outline Introduction Socket Programming – Cross Platform/Language Communication – .NET Socket Programming Thread Programming – More on Synchronization – Java wait() & notify() – .NET Thread Programming Assignment 1 – Multithreaded Dictionary Server Foundations: Revision Distributed Systems Principles and Paradigms Introduction Distributed Systems – Definitions • “A system in which hardware or software components located at networked computers communicate and coordinate their actions only by message passing.” (Colouris, Dollimore, Kindberg) • “A distributed system is a collection of independent computers that appear to the users of the system as a single computer.” (Tanenbaum and Van Steen) – Aspect we focused • Communication – Technology: Sockets • Concurrency – Technology: Threads Foundations Foundations: Revision Distributed Systems Principles and Paradigms Introduction Sockets – What did we talk about • Socket Abstraction • TCP/IP and UDP/IP stacks • Connection-oriented vs Connectionless Communication • Java & .NET Sockets – What is missing? • Advanced applications with Sockets • Cross-Platform / Language Socket Programming Today’s Focus Foundations: Revision Distributed Systems Principles and Paradigms Introduction Threads – What did we talk about • • • • • Thread Abstraction Thread/Process Relation Multithreading (server applications) Basic Synchronization Java Threads & Synchronization APIs – What is missing? • Advanced Synchronization Problems • .NET & Synchronization APIs Today’s Focus Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Socket Abstraction – Client-server based approach – Defined by a couple: <address, port> – Connection-Oriented Sockets • Based on TCP • Reliable but more “weighty” to manage • Stream based I/O – Connectionless Sockets • Based on UDP • Unreliable but light • Packet based I/O Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Java Sockets – Package: java.net.*; – Concepts: • • • • Full implementation of the model Stream based communication for TCP Packet based communication for UDP Exceptions for network errors Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Java Sockets – Package: java.net.*; – Classes: • Connection Oriented Communication (TCP) – java.net.ServerSocket (server component, always on) – java.net.Socket (client component, connection bound lifetime) – Stream-oriented data transfer » java.io.DataInputStream » java.io.DataOutputStream – Examples: SimpleServer.java & SimpleClient.java • Connectionless Communication (UDP) – java.net.DatagramSocket (client and server, send & receive) – java.net.DatagramPacket (packet abstraction, container of bytes) – Examples: UDPServer.java & UDPClient.java Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming .NET Sockets – Namespaces: • System.Net; • System.Net.Sockets; – Concepts: • • • • • Use of xxxClient classes to simplify communication Where is the Socket class ? Stream based communication for TCP Packet based communication for UDP Exceptions for network errors Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming .NET Sockets – Classes: • Connection Oriented Communication (TCP) – System.Net.Sockets.TcpListener » server component » always on – System.Net.Sockets.TcpClient » client component, » connection bound lifetime – Stream-oriented data transfer » System.Net.Sockets.NetworkStream » System.IO.StreamReader, StreamWriter – Examples: SimpleServer.cs & SimpleClient.cs • Connectionless Communication (UDP) – System.Net.Sockets.UdpClient Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Observations – Simple abstraction for network communication – General enough to serve different purposes – More importantly: Sockets are Platform / Language Independent! – But… • What about the examples? • It did work, but not as expected… • It is a problem about Java vs NET ? Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Observations – Wait a minute… • Sockets provide an independent abstraction……? • Yes…, but for transferring bytes! • As long as we limit ourselves to pure byte transfer the communication is platform/langue independent! – So..? • The examples where based on UTF strings! • String management made the difference! • Problem with string termination. Foundations: Revision Distributed Systems Principles and Paradigms Socket Programming Solutions – We use a byte-oriented processing! – We do not rely on readline methods! – We enforce define our protocol for string termination. Java .NET / Mono Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Thread Abstraction – – – – Statically ordered sequence of instructions. Piece of code that run concurrently with other threads. Each process has at least one thread. Threads • allow to perform multiple tasks at once within the same process • give the illusion of concurrency – Applications • • • • Asynchronous IO UI rendering Background task Increase throughput Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Concurrency management – Concurrent execution leads to: • • • • Races on share data Spurious writes and reads Inconsistency of state Undefined order of execution – How can we solve this? Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Concurrency management – Synchronization is the solution! • There exist some APIs that allow … – … exclusive access to shared data structures – … protecting the state of data – … atomic execution of a sequence of instruction • These APIs … – … are fundamental element of the language – … provide a solution to the problem discussed Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Concurrency management – Concurrency is a widely studied phenomenon – There exist models and abstractions to avoid concurrency issues • Semaphores • Monitors • Barriers – APIs and models changes according to the programming language – Mostly, the concept of Monitor is implemented Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Concurrency management – What is a Monitor? • It represents a guarded region where the execution of statements is exclusive • Classic operations are: – <enter> : acquires the exclusive access – <exit> : release the exclusive access • How to do it in Java? – synchronized(object){ } block; – synchronized modifier keyword; Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – synchronized(object obj){ } • Defines a simple guarded region in which only one thread is allowed to access • All the threads that have a synchronized(obj){ … } where obj is a reference to the same object, mutually exclude themselves – synchronized keyword • Provides a guarded region that covers the entire method to which the keyword is applied • The synchronization instance is the instance on which the method is called Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Observations • synchronized provides a way to: – acquire exclusive access to a resource – release this access once done • what if.. – the acquisition of a resource need is determined by a condition? – the condition needs to checked within a guarded region? – the threads need to be queued, to access the resource? – the condition is the result of multiple threads cooperating? Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Example • Producer – Consumer – One thread (or more) produces items – One thread (or more) consumes these items – The items are put in shared buffer among the threads Producer Consumer Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • Conditions – The producer thread can access the buffer only if there is room left to store an item – The consumer thread can access the buffer only if there is some item to consume • Problem – Can we implement this model with synchronized? – I mean….. optimally? Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Buffer { private Object[] items; private int empty; private int available; private boolean bEmpty; private boolean bFull; public Buffer(int length) { this.items = new Object[length]; this.empty = 0; this.available = 0; this.bFull = false; this.bEmpty = true; } public void put(Object item) throws Exception { if (this.bFull == true) { throw new Exception(“The buffer is full!”); } this.items[this.empty] = item; this.empty = ((this.empty + 1) % this.items.length); this.bFull = this.empty = this.available; this.bEmpty = false; } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public Object get() throws Exception { if (this.bEmpty == true) { throw new Exception(“The buffer is empty!”); } Object item = this.items[this.available]; this.available = ((this.available + 1) % this.items.length); this.bEmpty = this.available == this.empty; this.bFull = false; return item; } public boolean isFull() { return this.bFull; } public boolean isEmpty() { return this.bEmpty; } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Producer implements Runnable { private Buffer buffer; public Producer(Buffer buffer) { this.buffer = buffer; } public void run() { try { while(true) { synchronized(this.buffer) { if (this.buffer.isFull() == false) { Object item = this.produce(); this.buffer.put(item); } else { System.out.println(“Producer: no room for cheese!”); } } } } catch(Exception ex) { System.out.println(“Producer: exception: ” + ex.getMessage()); } } private Object produce() { return new Object(); } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs Producer – Consumer public class Consumer implements Runnable { private Buffer buffer; public Consumer(Buffer buffer) { this.buffer = buffer; } public void run() { try { while(true) { synchronized(this.buffer) { if (this.buffer.isEmpty() == false) { Object item = this.buffer.get(); this.consume(item); } else { System.out.println(“Consumer: no cheese for me!”); } } } } catch(Exception ex) { System.out.println(“Consumer: exception: ” + ex.getMessage()); } } private void consume(Object obj) { // whatever we need to do with it } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class ProducerConsumer { public static void main(String[] args) { // create the shared buffer and the producer // and consumer classes Buffer buffer = new Buffer(10); Producer producer = new Producer(buffer); Consumer consumer = new Consumer(buffer); // initialize the two threads... Thread p = new Thread(producer); Thread c = new Thread(consumer); // NOTE: let’s play with thread priorities and see // what is happening... p.start(); c.start(); } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • Observations – We have different execution traces with different thread priorities – In every case, we notice the following output lines: – Producer: no room for cheese! – Consumer: no cheese for me! – These lines identify conditions in which one of the two processes has acquired the resource without actually needing it – This is the result of a bad design! Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • How can we implement this better? – We need to ensure that the access to the resource is only obtained when appropriate – This means… – [Producer] when there is space in the buffer… – [Consumer] when there is some item to consume… • Can we implement such pattern in Java? – Yes, definitely! – By using: object.wait(), object.notify(), object.notifyAll() Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs - Object.wait(), Object.notify(), Object.notifyAll() • These are primitives that are used to implement more complex patterns • Object.wait() makes one thread wait until a specific call to Object.notify() or Object.notifyAll() is made (on the same instance). • Object.notify() signals the first waiting thread to stop the waiting process and proceeds the execution. • Object.notifyAll() does the same but wakes up all the threads waiting and a resource contention process is activated. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • Can we use Object.wait() & Object.notify() ? – Yes, definitely! – Producer: – Checks buffer.isFull() and waits if returned value is true. – Signals the buffer at the end of the insertion – Consumer: – Checks buffer.isEmpty() and waits if returned value is true. – Signal the buffer at the end of the extraction. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Producer implements Runnable { private Buffer buffer; public Producer(Buffer buffer) { this.buffer = buffer; } public void run() { try { while(true) { synchronized(this.buffer) { if (this.buffer.isFull() == true) { this.buffer.wait(); } Object item = this.produce(); this.buffer.put(item); this.buffer.notify(); } } } catch(Exception ex) { System.out.println(“Producer: exception: ” + ex.getMessage()); } } private Object produce() { return new Object(); } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Consumer implements Runnable { private Buffer buffer; public Consumer(Buffer buffer) { this.buffer = buffer; } public void run() { try { while(true) { synchronized(this.buffer) { if (this.buffer.isEmpty() == true) { this.buffer.wait(); } Object item = this.buffer.get(); this.consume(item); this.buffer.notify(); } } } catch(Exception ex) { System.out.println(“Consumer: exception: ” + ex.getMessage()); } } private void consume(Object item) { // whatever we need to do with it } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • Observations – This implementation is better… – But still, we are using a single lock instance to control two different conditions! – Buffer empty – Buffer full – This does not completely avoids the fact that the resource is acquired or tested without any need… – There still room for optimization…. – …by using two different conditions. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Buffer { private Object[] items; private int empty, available; private boolean bEmpty, bFull; private Object emptyHandle, fullHandle; public Buffer(int length) { this.items = new Object[length]; this.empty = 0; this.available = 0; this.bFull = false; this.bEmpty = true; this.emptyHandle = new Object(); this.fullHandle = new Object(); } public Object getEmptyHandle() { return this.emptyHandle; } public Object getFullHandle() { return this.fullHandle; } ……… Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public boolean isFull() { return this.bFull; } public boolean isEmpty() { return this.bEmpty; } public void put(Object item) throws Exception { synchsronize(this.fullHandle) { if (this.bFull == true) { throw new Exception(“The buffer is full!”); } } this.items[this.empty] = item; this.empty = ((this.empty + 1) % this.items.length); synchronized(this.emptyHandle) { this.bFull = this.empty == this.available; this.bEmpty = false; } } …. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public Object get() throws Exception { synchronized(this.emptyHandle) { if (this.bEmpty == true) { throw new Exception(“The buffer is empty!”); } } Object item = this.items[this.available]; this.available = ((this.available + 1) % this.items.length); synnchronized(this.fullHandle) { this.bEmpty = this.available == this.empty; this.bFull = false; } return item; } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Producer implements Runnable { private Buffer buffer; private Object full; public Consumer(Buffer buffer) { this.buffer = buffer; this.full = this.buffer.getFullHandle(); } public void run() { try { while(true) { synchronized(this.full) { if (this.buffer.isEmpty() == true) { this.full.wait(); } } Object item = this.produce(); this.buffer.put(item); } } catch(Exception ex) { System.out.println(“Consumer: exception: ” + ex.getMessage()); } } … } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class Consumer implements Runnable { private Buffer buffer; private Object empty; public Consumer(Buffer buffer) { this.buffer = buffer; this.empty = this.buffer.getEmptyHandle(); } public void run() { try { while(true) { synchronized(this.empty) { if (this.buffer.isEmpty() == true) { this.empty.wait(); } } Object item = this.buffer.get(); this.consume(item); } } catch(Exception ex) { System.out.println(“Consumer: exception: ” + ex.getMessage()); } } … } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer public class ProducerConsumer { public static void main(String[] args) { // create the shared buffer and the producer // and consumer classes Buffer buffer = new Buffer(10); Object full = new Object(); Object empty = new Object(); Producer producer = new Producer(buffer); Consumer consumer = new Consumer(buffer); // initialize the two threads... Thread p = new Thread(producer); Thread c = new Thread(consumer); // NOTE: let’s play with thread priorities and see // what is happening... p.start(); c.start(); } } Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Producer – Consumer • Observations – By separating the two conditions… – The producer process will only check the buffer ONCE and will be notified only if there is “room for cheese” – The consumer process will only check the buffer ONCE and will be notified only if there is “cheese” – The consumer will signal the producer – The producer will signal the consumer – This implementations solves the following problem: – The consumer signal itself … (useless) – The producer signal itself … (useless) This is possible because of wait & notify! Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – Is there more? • More complex synchronization problems • Package java.util.concurrent.*: – Introduced since Java SE 5.0 – A set of utility classes useful in concurrent programming. – Contains a set of small, standardized, extensible frameworks: » Executors » Queues » Timing » Concurrent collections – More on: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming Java Synchronization APIs – For you to read/explore: • Java Concurrency in Practice, B. Goez, T. Peierls, J. Bloch, J. Bowbeer, D. Holmes, and D. Lea, Addison Wesley, 2006. • Effective Java, 2nd Ed., J. Bloch, Prentice Hall, 2008. (Chap. 10) Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Main APIs: – Language: – lock(object obj) {…} statement (same as synchronized) – Namespace : – System.Threading – Classes: – Basic thread management: – Thread, ThreadPriority, ThreadStart, ThreadPool – Synchronization: – ManualResetEvent, AutoResetEvent – Interlocked, Monitor, Semaphore, Mutex – ReaderWriteLock – Timing: – Timer Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – lock(object obj) { … } – Provides a synchronization context in which only one thread is allowed to execute. – All the threads that open a lock statement on the same obj reference are synchronized and mutually excluded. – There is no equivalent for the synchronized method modifier in Java. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – System.Threading.Thread – Represents a Thread of execution. – The class is sealed (final in Java) and cannot be extended. – In order to create a thread it is necessary to provide a delegate (pointer to a method) ,which represents the method that will be run inside the thread. – .NET threads offer the basic APIs: – Start, Stop, Suspend, Resume, Join, Sleep, SpinWait, Interrupt – IsBackGround, IsAlive, Priority, Name, … Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – System.Threading.ThreadStart – Provides a simple way to configure a method that will be run in a thread. – Wraps a delegate: void methodname() – System.Threading.ParametrizedThreadStart – The same as the previous one but accepts a method that has a variable number of parameters – Wraps a delegate: void methodname(param obj[]) Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – System.Threading.ThreadPriority – Provides an enumeration of values that allow to set a qualitative value for the priority of threads – Values: – – – – – Highest AboveNormal Normal BelowNormal Lowest – Operating systems are not requested to honor the value set for the priority Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – System.Threading.ThreadPool – Provides a simple implementation of a pool of threads. – It can be used to post work items that will be executed asynchronously. – Main features: – MinThreads, MaxThreads – QueueUserWorkItem(WaitCallback) – QueueUserWorkItem(WaitCallback, object) – Where: – delegate: void WaitCallback(object stateInfo); Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – ManualResetEvent & AutoResetEvent – They provide the corresponding features implemented in: – Object.wait(), – Object.notify(), and Object.notifyAll() – A xxxResetEvent provides the following: – Encapsulates a binary state (signaled, not signaled). – Provides a handle for threads to wait until the state is signaled. – Provides other threads with a method to signal the state. – Can be initialized in any state (signaled, not signaled). Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – ManualResetEvent & AutoResetEvent – ManualResetEvent provides the wait handle that needs to be explicitly reset in order to signaled again. – AutoResetEvent returns to its original state once signaled. – Operations: – ManualResetEvent.WaitOne: waits for a signal – ManualResetEvent.Set: signals a thread that is waiting – ManualResetEvent.WaitAny, WaitAll: more complex waiting patterns. – ManualResetEvent.Reset: resets the status of the object. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Interlocked – Provides a synchronization context in which it is possible to increment or decrement an integer value. – It is a more practical alternative to lock(…) { … }. – Operations: – Interlock.Increment(ref int intValue) – Interlock.Decrement(ref int intValue ) – The use of this structure does not require the caller to setup any guarded region. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Monitor – Provides an implementation of the monitor concept. – It is a static class that operated on object references. – Operations: – – – – Monitor.Enter(object handle) Monitor.Wait(object handle) Monitor.Pulse, PulseAll(object handle) Monitor.Exit(object handle) – Observations: – Enter and Exit are used to acquire/reacquire the lock on handle. – Wait is used to temporarily release the lock and block the current thread. – Pulse/PulseAll, to signal one/all threads that are blocked on a wait call. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Semaphore – Provides an implementation of the integer semaphore concept. – Limits the number of threads that can access a resource concurrently. – Can be used to synchronize both Threads and Processes. – Operations: – Creation of an integer OS/local semaphore – Wait / Release operations. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Mutex – Provides an implementation of a binary semaphore. – Can be used to synchronize both Threads and Processes. – Only one thread/process at time owns the mutex. – Operations: – Creation of an integer OS/local mutex – WaitOne / ReleaseMutex operations. Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – ReaderWriterLock – Defines a lock that supports single writers and multiple readers. – The ReaderWriterLock object is the shared instance on which the locks are acquired and released. – Operations: – – – – – – IsReaderLockHeld IsWriterLockHeld AcquireReaderLock AcquireWriterLock ReleaseReaderLock ReleaseWriterLock Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Timer – Provides a way to executed a method at a repeated constant interval. – Operations: – Timer creation: – Timer(TimerCallback) – Timer(TimerCallback, object obj, int start, int interval) – … – Timer management: – Timer.Chnage(int start, int interval) – Timer.Dispose() Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – .NET Parallel Extensions • Implemented since .NET 4.0 • Provides advanced features for parallel programming – – – – – – Task Parallel library Parallel LINQ (PLINQ) Data Structures for Parallel Programming Parallel Diagnostic Tools Task Factories Task Schedulers • Reference: – http://msdn.microsoft.com/en-us/library/dd460693.aspx Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Parallel Extensions Foundations: Revision Distributed Systems Principles and Paradigms Thread Programming .NET Synchronization APIs – Examples • ThreadPriorities • Producer Consumer – By using lock – By using xxxResetEvents Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Multithreaded Dictionary Server – Concept • Build a client-server system • The server maintains a dictionary • The clients can query the dictionary for word meaning – Demonstrates the use of • Sockets (communication among nodes) • Threads (provide concurrent requests management and better performance) Problem: ******** Using a client-server architecture, design and implement a multi-threaded server that returns the meaning of a word as stored in a dictionary. Belo Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Scenario Process Request Process Request Client Process Client Process Client Process Server Process Process Request Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Guidelines – Client application: • Implement a method to query the dictionary: – Input: » string (word to look for) – Output: » status code (found, not found, error) » string (meaning(s) of the word) eventually array • Use sockets: – TCP and UDP are ok – Provide a reliable communication Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Guidelines – Server application: • Implement an server (always on) • Use any of – Thread per request – Thread per connection • Dictionary – Maintain the dictionary in a file – Maintain the index of the dictionary in a separate file – Use indexing for speeding up search Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Guidelines – General considerations • Provide error handling for all the functions – IO and input from user – Network communication • Fully customizable from console – Port & Address – Word to look for – Dictionary and index file to use Foundations: Revision Distributed Systems Principles and Paradigms Assignment 1 Marking, Schedule, and Venue – Total marks assigned: 10 – Deadline: Monday 31 August – What to deliver: • Source code (listing of all the files, zipped) • Documentation (report, class documentation) • Mail to: [email protected] – Demonstration: • Will be scheduled in Lab 217 • More on LMS about date and time. Foundations: Revision Distributed Systems Principles and Paradigms Summary Brief review of – Socket programming • Focus on inter platform/language communication – Thread programming • Focus on concurrency • More to come on the LMS website – Assignment 1 • Description • Deadline and details