In general, spinlocks pass the _______ criterion for locking, but fail miserably in the areas of _______ and performance.
Front
correctness, fairness
Back
Dijkstra's name for the POSIX sem_wait() call was ______ (), and for sem_post() it was ______ (). Hint: these are very short names!
Front
p, v
Back
When compiling a multi-threaded program (using GCC or Clang), you have to add the -_______ command-line switch to ensure the correct library is linked, and other configuration changes are made.
Front
pthread
Back
A data structure is considered ______ - ______ when it performs correctly even when accessed (via its APIs) by multiple threads concurrently.
Front
thread safe
Back
A(n) ______ concurrent ______ scales up much better than a precise one, at the expense of some precision.
Front
sloppy, counter
Back
Having one big lock that is used any time any critical section is accessed is a _______-_______ locking strategy, which can lead to inefficiency.
Front
coarse grained
Back
Assuming a shared resource has been initialized in another thread (without ascertaining that) is an example of a(n) ______ violation. You should use a condition variable or ______ to ensure the correct sequencing of the two operations.
Front
order, semaphore
Back
_______ _______ keeps two (or more threads) from accessing shared data at the same time, avoiding race conditions.
Front
mutual exclusion
Back
The threading API analogous to fork() is called _______ _ _______().
Front
pthread, create
Back
A complete solution to the bounded buffer problem uses both ______ semaphores (as mutexes) and counting semaphores that signal other ______ when a buffer slot is filled or available.
Front
binary, threads
Back
Unlike a fork call, the function that creates a new thread takes a(n) _______ _______ as an argument. It uses the value passed for that parameter as the starting point of the code the thread is executing.
Front
function pointer
Back
To facilitate the writing of correctly-functioning concurrent programs, the
_______ provides a few useful instructions we can use to build _______ primitives, which threads can then use to coordinate access to shared resources.
Front
hardware, synchronization
Back
Constantly polling a flag until its value changes is called _______-_______. It's effective but not efficient.
Front
spin waiting
Back
Once we have multiple _______ within a process, the order in which things happen is no longer entirely _______.
Front
threads, deterministic
Back
In multi-threaded programs, we often want some chunk of code to execute
_______, without being preempted before completing.
Front
atomically
Back
Encapsulating synchronization within a data structure's methods or functions allows application programmers to assume the data structure is thread-______, and use it from multiple threads without having to worry about handling ______ conditions.
Front
safe, race
Back
Above all else, a locking mechanism must guarantee _______ _______. Otherwise, it might allow multiple threads to enter a critical section simultaneously.
Front
mutual exclusion
Back
A(n) ______ semaphore can be used to enforce mutual exclusion, replacing a lock. You just have to set its initial value to ______.
Front
binary, 1
Back
Using a separate lock for each separate shared resource is a _______-_______ locking strategy that can increase concurrency.
Front
fine grained
Back
The most basic way of accomplishing mutual exclusion when using the pthread library is to create a(n) lock, which is a variable of type _______ _ _______ _t
Front
pthread, mutex
Back
Instead of spin waiting, the function that acquires a lock can use the _______() system call to force a context switch if the flag it's waiting for has not yet changed.
Front
yield
Back
It is important to consider scaling to more than 1 or 2 threads when making a data structure ______ - safe. Otherwise, using it might undo all benefits of ______.
Front
thread, concurrency
Back
When no thread is in its corresponding _______ section, the lock is said to be _______.
Front
critical, available
Back
When a _______ is in the critical section guarded by a particular lock, that lock should be _______ by that thread.
Front
thread, acquired
Back
One way to break the ______-and-______ condition necessary for deadlock is to require threads to acquire all of the locks they're going to hold simultaneously in one fell swoop. This, sadly, is not practical in many settings.
Front
hold, wait
Back
In the context of locking, _______ means giving each thread contending for the lock a chance at acquiring it once it's free. On the other hand, if a thread never gets a chance to run, it's said to be suffering from _______.
Front
fairness, starvation
Back
One way to scale a concurrent counter up to many threads is to store a separate counter for each ______, which occasionally gets transferred to a single ______ counter.
Front
thread, global
Back
All threads in a process share both code and the _______ section of memory, but each thread has its own _______ (often called thread-local storage).
Front
heap, stack
Back
Every _______ section in a multi-threaded program needs to be "protected" by a(n) _______, which provides mutual exclusion.
Front
critical, lock
Back
Each thread in a process keeps separate _______ information, including the _______ register (which keeps track of where the program is fetching instructions from).
Front
state, PC
Back
The simplest type of POSIX lock is called a(n) _______ because it is used to provide _______ exclusion between threads.
Front
mutex, mutual
Back
A monitor is a programming language feature that automatically ______ a lock whenever a method for a particular object is called, and ______ it when the method exits.
Front
acquires, releases
Back
Without some intentional control, multi-threaded access to shared data will lead to a(n) _______ _______ where the results depend on the timing of the code's execution.
Front
race condition
Back
All of a thread's state information is saved in a(n) ______________, similar to the ______________ stored for each process.
Front
thread control block, process control block
Back
______ lists and ______ are data structures that are commonly accessed concurrently, so it makes sense for an OS or language library to provide them.
Front
linked, queues
Back
You can guarantee that a block of instructions will execute _______ by disabling _______ before starting its execution. This approach is very heavy-handed, however, and can cause other problems.
Front
atomically, interrupts
Back
When moving a thread from the _______ state to the blocked state due to an unavailable lock, the OS has to add the thread to a(n) _______ so it gets a fair chance to run when the lock becomes available.
Front
running, queue
Back
To use locks in a multi-threaded program, you first declare a(n) lock _______. For the simplest type of POSIX lock, it would be of type pthread_ _______ _t.
Front
variable, mutex
Back
The test-and-set instruction is often known as the ________ ________ instruction, since it swaps the contents of a register with the contents of a memory location in a single instruction.
Front
atomic exchange
Back
We can use Dijkstra's ______ to make one thread wait for another to signal the completion of some task. Thus, they can take the place of ______ variables
Front
semaphores, condition
Back
Code that accesses shared data in a multi-threaded program is known as a(n) _______ _______.
Front
critical section
Back
A correct solution to the ______ ______ problem relies on a thread-safe queue that holds the items produced and consumed by multiple threads concurrently.
Front
bounded buffer
Back
As an alternative to spin waiting, the function that acquires a lock can move the calling thread from the _______ state to the _______ state, where it doesn't take up any CPU time until the lock becomes available.
Front
running, blocked
Back
A semaphore is an object with a(n) ______ value that we can manipulate using a routine to ______ its value and another to attempt to decrement its value.
Front
integer, increment
Back
To avoid spin waiting, a thread can voluntarily move itself from the _______ state to the _______ state by calling yield().
Front
running, ready
Back
The threading API analogous to wait() is called _______ _ _______().
Front
pthread, join
Back
When compiling a multi-threaded program (using GCC or Clang), you have to add the -_______ command line switch to ensure the correct library is linked, and other configuration changes are made.
Front
pthread
Back
The basic abstraction introduced for concurrency is that of a(n) _______, which breaks the classic view of a single point of execution within a program.
Front
thread
Back
Because C lacks native support for generics, the thread creation function both accepts and returns a(n) _______ _______. This allows it to receive and pass back any type of value, at the expense of a cast in both directions.
Front
void pointer
Back
Using a pointer after checking that it's not null but without locking it is an example of a(n) ______ violation. You should precede the check with code that ______ a lock and doesn't release it till after you're done using the pointer.
Front
atomicity, acquires
Back
Section 2
(17 cards)
there exists a circular chain of threads such that each thread hold one or more resources that are being requested by the next thread in the chain
Front
circular wait
Back
threads hold resources allocated to them while waiting for additional resources
Front
hold and wait
Back
What are the four causes of deadlock?
Front
mutual exclusion, hold and wait, circular wait, no preemption
Back
The idea that two threads ________ at a point of execution and neither is allowed to proceed until both have arrived
Front
rendezvous
Back
barrier that locks itself after all the threads have passed through
Front
reusable barrier
Back
threads claim exclusive control resources that they require (ex. thread grabs a lock)
Front
mutual exclusion
Back
guarantees that only one thread access the shared variable at a time. (Like a talking stick)
Front
mutex
Back
multiple threads execute code but not until all threads have arrived. (rendezvous but with more threads)
Front
barrier
Back
resources cannot be forcibly removed from threads that are holding them
Front
no preemption
Back
multiple threads are allowed to run in the critical section at the same time, but an upper limit is enforced on the number of concurrent threads. Like a bouncer for a club where the room has a max capacity and when one person leaves, another can enter
Front
multiplex
Back
Where one thread sends a signal to another thread to indicate that something has happened
Front
signaling
Back
List the concurrent data structures
Front
counters, linked lists, queues, hash table
Back
makes it so that it is not possible to signal until there is a thread waiting; the semaphore value is never positive
Front
queue
Back
There are four necessary conditions for deadlock to occur: mutual exclusion, hold-and-wait, no ______, and ______ wait.
If any of these conditions is not met, deadlock cannot occur.
Front
preemption, circular
Back
OSTEP classifies concurrency bugs into two major categories, based on whether they're related to ______ or not.
Front
deadlock
Back
To solve the problem of deadlock, it is sufficient to remove any of the ______ (number) necessary conditions. Sadly, this is often not practical, so instead, some systems choose to simply allow deadlock to happen, then ______ that it has happened and recover from the problem.
Front
four, detect
Back
Non-deadlock concurrency bugs can be classified into two major types: ______ violations and ______ violations.