{
"q01": {
"type": "blank",
"question": "\n\nA ____ is a synchronization primitive that consists of an ____ value that\nwe can manipulate with two routines:\n\n\n
\n\n
____: This function decrements the value of the semaphore and\n waits if the value of the semaphore is negative.
\n\n
____: This function increments the value of the semaphore and\n then wakes up any waiting threads.
\n \n\n"
},
"q02": {
"type": "multiple",
"question": "\n\nRegarding using semaphores to implement locks and condition variables,\nwhich of the following statements are true (choose all that apply)?\n\n\n",
"responses": {
"lock_init": "To make a lock (binary semaphore), we initialize the semaphore to 1.",
"cond_init": "To make a condition variable, we initialize the semaphore to 1.",
"lock_call": "To make a lock (binary semaphore), we first sem_post, perform the critical section, and then sem_wait",
"cond_call": "To make a condition variable, we use sem_post to signal and sem_wait to wait."
}
},
"q03": {
"type": "multiple",
"question": "\n\nRegarding reader-writer locks, which of the following statements are true\n(choose all that apply)?\n\n\n",
"responses": {
"concurrency": "Reader-writer locks allow for multiple concurrent readers as long as there are no writers.",
"writers": "Reader-writer locks suspend all readers once a writer requires access.",
"starvation": "Reader-writer locks are prone to starvation problems.",
"overhead": "Reader-writer locks generally improve performance over simple and fast locking primitives."
}
},
"q04": {
"type": "single",
"question": "\n\nTo solve the Dining Philosopher's problem, the book proposes the following\nsolution:\n\n\n",
"responses": {
"order": "Change the order in which the last philosopher acquires the forks.",
"waiter": "Have a waiter direct which philosophers can eat.",
"starve": "Just let some of the philosophers starve.",
"rdrn": "Have philosophers eat in round-robin fashion.",
"forks": "Buy more forks."
}
},
"q05": {
"type": "blank",
"question": "\nTwo types of non-deadlock concurrency bugs are:\n\n\n\n\n
____: These bugs occur when the assumption of atomicity is incorrect.
\n\n
____: These bugs occur when the desired order of operations is\nnot enforced during execution.
\n\n\n"
},
"q06": {
"type": "blank",
"question": "\n\nDeadlock occurs when the following four conditions hold:\n\n\n\n\n\n
____: There exists a circular chain of threads such that each\nthread holds one or more resources that are being requested by the next\nthread in the chain.
\n\n
____: Resources cannot be forcibly removed from threads that are\nholding them.
\n\n
____: Threads hold resources allocated to them while waiting for\nadditional resources.
\n\n
____: Threads claim exclusive control of resources that they\nrequire.
\n\n\n"
},
"q07": {
"type": "multiple",
"question": "\n\nWhich of the following are ways to prevent deadlock (choose all that apply)?\n\n\n",
"responses": {
"ordering": "Provide some form of ordering to circumvent circular waiting.",
"holding": "Make sure we always acquire locks one at a time.",
"livelock": "Prefer methods that utilize livelock instead of deadlock.",
"lockfree": "Avoid locks by using atomic hardware instructions."
}
},
"q08": {
"type": "blank",
"question": "\n\nRather than prevent deadlock, we can instead try to avoid it by having a\nsmart ____ that will consider the dependencies between threads or by having a\nservice that ____ deadlock and provides ____ techniques.\n\n\n"
}
}