lec17 - (* Programs that use system threads must be linked...

Info iconThis preview shows pages 1–3. Sign up to view the full content.

View Full Document Right Arrow Icon
(* Programs that use system threads must be linked as follows: * ocamlc -thread other options unix.cma threads.cma other files * ocamlopt -thread other options unix.cmxa threads.cmxa other files * * To get a version of the ocaml top level with threads, run: * ocamlmktop -thread unix.cma threads.cma -o mytop * Then run the resulting executable: ./mytop -I +threads *) (* PRODUCER/CONSUMER PATTERN using mutex. * * A shared queue, with one group of threads storing data in the queue * (producers) and the other removing it (consumers). Each party * accessing the queue excludes the others. * * To guarantee proper operation, the queue is manipulated by only one * party at a time in order to ensure that the insert and remove * operations on the queue maintain their integrity, using a mutex to * guarantee exclusion. * *) let f = Queue.create() and m = Mutex.create () l let produce i p d = incr p ; Thread.delay d ; (* Simulate time to produce something by sleeping *) print_string("Producer " ^ string_of_int(i) ^ " has produced " ^ string_of_int(!p) ^ "\n"); flush stdout (* Lock the mutex (blocking until it is free) before adding to the * queue, unlock when done. For illustration here printing is done in * the critical section, but generally doing IO with a mutex locked is * not a good idea because it prevents others who might be waiting for * the mutex from running, while doing something that is non-CPU * intensive. *) let store i p = Mutex.lock m ; Queue.add (i,!p) f ; print_string("Producer " ^ string_of_int(i) ^ " has added its " ^ string_of_int(!p) ^ "-th product\n"); flush stdout; Mutex.unlock m (* A producer has a product counter p and a time d it takes to produce * a unit. They produce a unit and then store it, saving both producer * id and product counter. store gets the lock before accessing the * queue and releases it after. *) let producer (n,i) = let p = ref 0 and d = Random.float 2. in for j = 1 to n do produce i p d ; store i p ; Thread.delay (Random.float 2.5) done;
Background image of page 1

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
print_string("Producer " ^ string_of_int(i) ^ " is exiting.\n"); flush stdout (* A consumer tries to get a unit, with try/catch handling when * queue is empty. Prints out own id, and if gets product then * producer id and product id *) let consumer (n,i) = for j = 1 to n do Mutex.lock m ; ( try let ip, p = Queue.take f in print_string("Consumer " ^ string_of_int(i) ^ " has taken product (" ^ string_of_int(ip) ^ "," ^ string_of_int(p) ^ ")\n"); flush stdout with Queue.Empty -> print_string("Consumer " ^ string_of_int(i) ^ " has returned empty-handed\n"); flush stdout); Mutex.unlock m ; Thread.delay (Random.float 2.5) done; print_string("Consumer " ^ string_of_int(i) ^ " is exiting.\n"); flush stdout (* Let's try four producers and four consumers *) ( let test_producer_consumer () = for i = 1 to 4 do ignore (Thread.create producer (25,i)); ignore (Thread.create consumer (50,i)) done (* PRODUCER/CONSUMER REVISITED with condition variables, so consumer * waits for goods if there are none. * * Mutual exclusion used above is very coarse grained, it is often
Background image of page 2
Image of page 3
This is the end of the preview. Sign up to access the rest of the document.

This note was uploaded on 10/25/2009 for the course PHYS 2214 at Cornell University (Engineering School).

Page1 / 7

lec17 - (* Programs that use system threads must be linked...

This preview shows document pages 1 - 3. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online