threads and concurrency def consumer()while truecv acquire(while not item_is_available()cv wait(wait for an item to show up cv release(consume_item( subtle aspect of using condition variables is that if there are multiple threads waiting on the same conditionthe notify(operation may awaken one or more of them (this behavior often depends on the underlying operating systembecause of thisthere is always possibility that thread will awaken only to find that the condition of interest no longer holds this explainsfor instancewhy while loop is used in the consumer(function if the thread awakensbut the produced item is already goneit just goes back to waiting for the next signal working with locks great care must be taken when working with any of the locking primitives such as lockrlockor semaphore mismanagement of locks is frequent source of deadlock or race conditions code that relies on lock should always make sure locks get properly released even when exceptions occur typical code looks like thistrylock acquire(critical section statements finallylock release(alternativelyall of the locks also support the context management protocol which is little cleanerwith lockcritical section statements in this last examplethe lock is automatically acquired by the with statement and released when control flow leaves the context alsoas general rule you should avoid writing code where more than one lock is acquired at any given time for examplewith lock_acritical section statements with lock_bcritical section on statements this is usually good way to have your application mysteriously deadlock although there are strategies for avoiding this (for examplehierarchical locking)you're often better off writing code that avoids this altogether lib fl ff