outline
play

Outline 0024 Spring 2010 13 :: 2 CSP: communicating sequential - PowerPoint PPT Presentation

Outline 0024 Spring 2010 13 :: 2 CSP: communicating sequential processes Synchronous communication with global channels Channels are the only state that is shared between threads No shared objects, shared


  1. Outline �� 0024 Spring 2010 � – 13 :: 2 – �

  2. CSP: communicating sequential processes � Synchronous communication with global channels � � � Channels are the only state that is shared between threads � No shared objects, shared references, or shared arrays � � � Only data can be transmitted -- no point to send a reference � Restrictive? � � � Yes and no. � Too restrictive to write interesting programs? � 0024 Spring 2010 � – 13 :: 3 – �

  3. More details � Unit of transfer (“message”) � � � Basic model: integers ( int ) � � � Could be any object � What should the consumer do if there is no message? � � � Wait. � What should the producer do if the consumer is not ready to receive a message? � � � Wait. � Should messages be buffered? � � � No. � � � But we � ll see in a few minutes how to create buffers � 0024 Spring 2010 � – 13 :: 4 – �

  4. Operations � Many options for syntax. � Send: output data into channel ch � � � ch ! data � � � ch <- data � � � ch.write(data) � � � put(ch, data) � Receive: get data from channel (“input”) � � � ch ? data � � � ch -> data � � � data = ch.read() � � � get(ch, data) � 0024 Spring 2010 � – 13 :: 5 – �

  5. Operations, continued � Think of “data” as an int or another useful object � � � The type/class must be known � Extensions (in the literature) : get(ch, data 1 , data 2 , .., data N ) � Sometimes you want to use a “signal” � � � Could be incoded in an integer � � � Example: consumer can ask for more data (signal_1) or stop the stream (signal_2) � � � Better to be explicit: give it a name � � � Need mechanism to send and receive a signal � 0024 Spring 2010 � – 13 :: 6 – �

  6. Operations, continued � get(ch, signal_X()) � // also written as ch?signal_X() � From channel ch, input the signal “signal_X”. Refuse to input any other signal � � � Example (in a producer): get(ch_from_consumer, more()) � put(ch, signal_Y()) � // also written as ch!signal_Y() � Send signal “signal_Y” to ch � get(ch[j], x) -- on channel ch[j] read x � 0024 Spring 2010 � – 13 :: 7 – �

  7. Why bother? � Coupling of data exchange (between threads) and synchronization � � � Synchronization implied - only when data are ready (to receive) or can be sent � One mechanism to deal with � Input/output are well-understood (and necessary) � � � By extending get/put to communicate with another thread we can deal with multiple threads � No need to pick one from a long list of synchronization primitives � � � Semaphores? � � � Monitors? � � � Event queues? � 0024 Spring 2010 � – 13 :: 8 – � � � Many others that we have not covered in class �

  8. Why bother in this class? � Proofs are simpler, reasoning is simpler � � � No need to deal with temporal logic: receiving an item implies synchronization � Not all systems support shared objects/references � � � Java works fine for a multi-processor/multi-core system -- but what if you want to run on a workstation cluster ? � � � .. on a cloud ? � � � .. on a collection of volunteered home computers � CSP is a model for (simple) message passing � � � CSP really a model - must be embedded in a programming language � � � There is a Java package � � � I � ll deviate from the Java syntax for now a little � Model to deal with streams � 0024 Spring 2010 � – 13 :: 9 – �

  9. Sequencing of communication � Recall: all variable names are local, ch1, ch2 connect A & B � Thread A: � Thread B: � . � y = 5; � . � . � Get(ch1, x) -- wait for B � . � . � Put(ch1, y+1) � -- transfer happens � -- transfer happens, x now 6 � . � . � Put(ch2, 2*x) -- wait for B � . � . � Get(ch2, y) � -- transfer happens � -- transfer happens � 0024 Spring 2010 � – 13 :: 10 – �

  10. Broadcasting � Problem: take input stream and forward the data items to two “worker” threads � � � in, out1, out2: channels � Thread B: � while ( true ) { � get(in, item); � put(out1, item); � put(out2, item); � } � 0024 Spring 2010 � – 13 :: 11 – �

  11. Experiment � Write a simple CSP program to perform a “join” of two streams: take input from two input channels and forward it to an output channel. Forward as fast as possible, you must maintain relative order (as defined by each channel) but the inputs from both channels can be mixed freely. � 0024 Spring 2010 � – 13 :: 12 – �

  12. Problems? � What would you like to add to CSP to make it possible to write such a program? � What is the source of the problem? � 0024 Spring 2010 � – 13 :: 13 – �

  13. Guarded commands � A guarded command consists of a guard and a block (of statements) � � guard -> { block } � If the guard evaluates to true, the statement block is executed. � Guards can contain only logical expressions without side effects � � � Input is allowed � � � One input operation, must be the last of a logical AND � � � Output is not allowed � 0024 Spring 2010 � – 13 :: 14 – �

  14. Guarded commands � Can be grouped in a select clause � select { � � guard1 -> {block1}; � � guard2 -> {block2}; � …. � } � Any guard that evaluates to true may trigger execution of its block. � Only one block (of those with a guard that evaluates to true) is executed. � � � Select fails if no guard evaluates to true � 0024 Spring 2010 � – 13 :: 15 – �

  15. Failure and waiting � select { � � (j < 10) -> {j --;}; � (get(ch, x)) -> {j = x;}; � } � If the thread that provides input to “ch” terminates (or has terminated) the corresponding “get” operation fails. � Otherwise get waits for input. � Same for put. � 0024 Spring 2010 � – 13 :: 16 – �

  16. Looping � while select { � guarded command 1; � guarded command 2; � guarded command n; � } � Loop until all guarded commands fail. � 0024 Spring 2010 � – 13 :: 17 – �

  17. Solution (one) � Write a simple CSP program to perform a “join” of two streams: take input from two input channels and forward it to an output channel. Forward as fast as possible, you must maintain relative order (as defined by each channel) but the inputs from both channels can be mixed freely. � while select { � get(in1, x) -> put(out, x); � get(in2, x) -> put(out, x); � }; � Terminates if both sources for in1 and in2 have terminated. � 0024 Spring 2010 � – 13 :: 18 – �

  18. Non-determinism � 0024 Spring 2010 � – 13 :: 19 – �

  19. Comments � 0024 Spring 2010 � – 13 :: 20 – �

  20. Division with remainder � Construct a program that accepts a positive dividend and divisor and returns their integer quotient and remainder. � 0024 Spring 2010 � – 13 :: 21 – �

  21. int x, y; � while select { � get(in, x, y) -> { int q, r; � q = 0; � r = x; � � � � � while select { � � � � � (r � y) -> { r = r - y; q++; }; � � � � � }; � � � � � put(out, q, r); � }; � }; � 0024 Spring 2010 � – 13 :: 22 – �

  22. Buffering � CSP provides synchronous communication. If you need buffering you must introduce a separate buffer thread. � � � Buffer is bounded � Problem: write the program for a buffer thread. � � � Assume we want to buffer up to 10 integers � � � Buffer takes input as it is generated by “producer” � � � Passes on buffered data as requested by “consumer” � � � Consumer send signal “more” if it is ready for input � 0024 Spring 2010 � – 13 :: 23 – �

  23. We need a buffer array, counters for input and output, plus three channels to connect to. � � � source: producer; sink: consumer; request: consumer signals it � s ready for data � int [ ] buffer = new int[10]; � int count_in = 0; � int count_out = 0; � while select { � ((count_in < count_out+10) � � (get(source,buffer[count_in mod 10]))) -> { count_in++;}; � ((count_out < count_in) � (get(request,more())) -> { � � put(sink, buffer[count_out mod 10]; count_out++; } ; � }; � 0024 Spring 2010 � – 13 :: 24 – �

  24. Why (hidden) buffering is bad � Programs can fail in unexpected ways if they assume an infinite buffer � � � No buffer is infinite � � � Different systems may approximate the infinite buffer differently � Problem: a producer sends a set (sequence) of data to a consumer. Then – using a different channel – it sends the size of the set. � The consumer reads the size of the set to determine how many items to retrieve. � 0024 Spring 2010 � – 13 :: 25 – �

  25. Implementation strategy � 0024 Spring 2010 � – 13 :: 26 – �

  26. Simple solution � Thread Consumer: Thread Producer: int j=0; int [ ] b; int count; int j = 0; int [ ] b; while (cond) { get(ch2, count); put(ch1, b[j++]); while (j<count){ } get(ch1,b[j++]); put(ch2, j); } 0024 Spring 2010 � – 13 :: 27 – �

  27. Real solution � 0024 Spring 2010 � – 13 :: 28 – �

  28. Snapshot � � � P C Read so far � Filled up to here � 0024 Spring 2010 � – 13 :: 29 – �

  29. Real solution 2 � 0024 Spring 2010 � – 13 :: 30 – �

Recommend


More recommend