🎓 BookMCQ
← Back to 5. Process Synchronization

📝 Pthreads Synchronization in Operating System (66 MCQs)

📖 From Operating System • 5. Process Synchronization • 66 questions available

What is Pthreads Synchronization in Operating System?

Definition:
Pthreads synchronization defines portable POSIX thread primitives including mutexes, condition variables, barriers, and read-write locks with standardized attributes for cross-platform threading.

Example:
Creating a mutex with pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE)pthread\_mutexattr\_settype(\&attr, PTHREAD\_MUTEX\_RECURSIVE) allows the same thread to lock mm multiple times without deadlocking.

Reason:
Pthreads standardization enables source-code portability across Unix-like systems and provides rich configurability (error-checking, recursive, robust) to match diverse application requirements.

12
Easy
38
Medium
16
Hard

📝 All Pthreads Synchronization in Operating System MCQs

Q1. Which API provides mutex locks, condition variables, and read-write locks for thread synchronization at the user level?

A.Solaris thread API
B.Pthreads API ✅
C.Kernel thread API
D.Win32 thread API
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: The Pthreads API is explicitly designed for user-level thread synchronization. Other options represent different threading models or APIs that may have their own synchronization primitives, but Pthreads is the standard for UNIX-like systems.

Q2. What is the most fundamental synchronization technique used with Pthreads?

A.Condition variables
B.Read-write locks
C.Mutex locks ✅
D.Semaphores
💡 Difficulty: easy | ✅ Correct: C

📖 Explanation: Mutex locks are described as the fundamental synchronization technique in the Pthreads API. They serve as the basis for protecting critical sections of code. While the other options are also useful synchronization methods, mutexes are the most basic.

Q3. Which Pthreads data type represents a mutex lock?

A.pthread_t
B.pthread_mutex_t ✅
C.sem_t
D.mutex_t
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: The text specifically identifies `pthread_mutex_t` as the data type used for mutex locks in Pthreads. `pthread_t` is for threads, and `sem_t` is for POSIX semaphores. `mutex_t` is not a standard Pthreads data type.

Q4. Which function is used to initialize a Pthreads mutex?

A.pthread_mutex_init() ✅
B.pthread_mutex_create()
C.pthread_mutex_alloc()
D.pthread_mutex_new()
💡 Difficulty: easy | ✅ Correct: A

📖 Explanation: The `pthread_mutex_init()` function is used to initialize a mutex. By passing a pointer to the mutex and a second parameter (e.g., NULL) for attributes, the mutex is initialized with the default settings.

Q5. Which function is used by a thread to acquire a mutex lock in the Pthreads API?

A.pthread_mutex_lock() ✅
B.pthread_mutex_acquire()
C.pthread_mutex_wait()
D.pthread_mutex_enter()
💡 Difficulty: easy | ✅ Correct: A

📖 Explanation: The function to acquire a Pthreads mutex is `pthread_mutex_lock()`. This is consistent with the terminology used in the provided text. If the lock is held by another thread, the calling thread will block until it becomes available.

Q6. How are errors indicated by Pthreads mutex functions?

A.They return a negative value
B.They return a nonzero error code ✅
C.They throw an exception
D.They set a global error variable
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: The text explicitly states that all mutex functions return 0 on correct operation and a nonzero error code if an error occurs. This is a standard convention in C-based system APIs.

Q7. To which standard do POSIX semaphores belong?

A.Pthreads standard
B.POSIX SEM extension ✅
C.System V IPC
D.Solaris thread library
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: POSIX semaphores are not part of the Pthreads standard. They are defined in the POSIX SEM extension, which specifies additional functionality for synchronization beyond what is in the core Pthreads API.

Q8. What is the primary distinction between named and unnamed POSIX semaphores?

A.Named semaphores are faster
B.Unnamed semaphores can be shared across processes
C.Named semaphores have a name in the file system and can be shared by unrelated processes ✅
D.Unnamed semaphores are a part of the Pthreads standard
💡 Difficulty: easy | ✅ Correct: C

📖 Explanation: The core difference is that a named semaphore has a file-system name and can be shared between unrelated processes, making it more versatile for inter-process communication. Unnamed semaphores are limited to threads within the same process.

Q9. Which function initializes an unnamed POSIX semaphore?

A.pthread_sem_init()
B.sem_initialize()
C.sem_create()
D.sem_init() ✅
💡 Difficulty: easy | ✅ Correct: D

📖 Explanation: The `sem_init()` function is specifically used to create and initialize an unnamed semaphore. The other function names are not the standard POSIX semaphore initialization function.

Q10. In the `sem_init()` function, what does the second parameter (the flag) indicate?

A.The initial value of the semaphore
B.The priority of the semaphore
C.The level of sharing for the semaphore ✅
D.The type of semaphore (named or unnamed)
💡 Difficulty: easy | ✅ Correct: C

📖 Explanation: The flag passed as the second parameter to `sem_init()` determines the sharing level. A value of 0 restricts sharing to threads of the same process, whereas a non-zero value allows other processes to access the semaphore.

Q11. What is the Pthreads name for the classical semaphore `signal()` operation?

A.sem_signal()
B.sem_post() ✅
C.sem_v()
D.sem_release()
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: The POSIX semaphore API uses `sem_post()` to perform the `signal()` operation on a semaphore. `sem_wait()` is used for the `wait()` operation. The other options are not the standard POSIX function names.

Q12. What is the correct function call to protect a critical section using a semaphore `sem`?

A.sem_wait(&sem) and sem_signal(&sem)
B.sem_lock(&sem) and sem_unlock(&sem)
C.sem_wait(&sem) and sem_post(&sem) ✅
D.sem_acquire(&sem) and sem_release(&sem)
💡 Difficulty: easy | ✅ Correct: C

📖 Explanation: To protect a critical section with a semaphore, `sem_wait()` is used to acquire it before the critical section, and `sem_post()` is used to release it after. This correctly enforces mutual exclusion for the critical section.

Q13. A developer needs to create a semaphore that can be accessed by multiple unrelated processes. Which type of POSIX semaphore should be used?

A.Unnamed semaphore
B.Named semaphore ✅
C.Anonymous semaphore
D.Process-local semaphore
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: Named semaphores are explicitly designed for sharing between unrelated processes because they have a name in the file system. Unnamed semaphores are limited to threads of the same process. The other options are not standard POSIX types.

Q14. What is the behavior of `pthread_mutex_lock()` when a mutex is already held by another thread?

A.It returns an error code
B.It spins in a loop until the lock is released
C.The calling thread is blocked until the owner calls `pthread_mutex_unlock()` ✅
D.It attempts to acquire the lock and immediately returns a value indicating failure
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: `pthread_mutex_lock()` is a blocking call. If the mutex is currently locked by another thread, the calling thread will block (i.e., go to sleep) and be woken up when the mutex becomes available. It does not return an error in this case.

Q15. Which of the following is NOT provided by the core Pthreads API for thread synchronization?

A.Mutex locks
B.Condition variables
C.Read-write locks
D.POSIX Semaphores ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: The core Pthreads API provides mutex locks, condition variables, and read-write locks. POSIX semaphores are not part of the Pthreads standard; they are an extension. The text explicitly notes that many systems provide semaphores, but they belong to a different POSIX standard extension.

Q16. In the Pthreads API, how does a thread release a mutex lock it currently holds?

A.By calling `pthread_mutex_release()`
B.By calling `pthread_mutex_unlock()` ✅
C.By calling `pthread_mutex_post()`
D.By exiting the critical section
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The function to release a mutex is `pthread_mutex_unlock()`. This is the counterpart to the lock function. A thread must own the mutex to unlock it successfully; attempting to unlock a mutex not owned leads to undefined behavior.

Q17. Given the following code snippet: `pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL);`, what is the state of the mutex after the `init` function call?

A.It is locked.
B.It is unlocked. ✅
C.It is in an undefined state.
D.It is in a recursive state.
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The `pthread_mutex_init()` function initializes the mutex to its default attributes and puts it in an unlocked state. The second parameter (NULL) indicates the use of default attributes. It is only after a call to `pthread_mutex_lock()` that the mutex becomes locked.

Q18. A thread calls `pthread_mutex_unlock()` on a mutex it does not own. What is the most likely outcome?

A.The mutex is unlocked successfully.
B.The call returns an error.
C.The calling thread is blocked.
D.The behavior is undefined. ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: The text states that functions return a non-zero error code on error. However, unlocking a mutex held by another thread is a serious programming error. In most Pthreads implementations, the behavior is considered undefined, but a common safe implementation might return an error. The safest and most technically accurate answer is that the behavior is undefined or results in an error. Given the text states they return an error, B is the most correct answer based on the provided material.

Q19. What is the role of the 'flag' parameter in the `sem_init(&sem, 0, 1);` function call?

A.It sets the initial value of the semaphore to 0.
B.It indicates the semaphore is named.
C.It restricts sharing to threads belonging to the same process. ✅
D.It makes the semaphore a spinlock.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The flag parameter controls the sharing of the semaphore. A value of 0 means the semaphore is private to the process, meaning only threads within that process can access it. A non-zero value would allow other processes to access the semaphore, making it suitable for inter-process synchronization.

Q20. Which of the following correctly describes the return values for Pthreads mutex and POSIX semaphore functions?

A.0 on error, nonzero on success
B.0 on success, nonzero on error ✅
C.1 on success, -1 on error
D.A boolean value indicating success
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The text clearly states that both mutex and semaphore functions return 0 upon successful operation and a nonzero error code if an error occurs. This return convention is common in system-level C functions to provide information about the success or failure of the call.

Q21. What makes extensions like spinlocks less portable across different Pthreads implementations?

A.They are not part of the Pthreads API
B.They have a different return value convention
C.They depend on specific hardware architectures ✅
D.They are designed for single-threaded programs
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The text notes that not all extensions are portable because they may have implementation-specific behavior. While spinlocks are an extension, the reason for non-portability is typically tied to hardware-specific optimizations (like atomic CPU instructions) or differing implementation details, making option C the most direct technical reason.

Q22. A developer is designing a system that requires synchronization between two unrelated applications. Which synchronization primitive is most appropriate?

A.A mutex lock using Pthreads
B.An unnamed semaphore
C.A condition variable
D.A named semaphore ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: Named semaphores are explicitly designed to synchronize multiple unrelated processes. Mutex locks, unnamed semaphores, and condition variables (without shared memory) are generally limited to threads within a single process and are not suitable for synchronizing separate, unrelated applications.

Q23. Which of the following is a correct sequence of operations for protecting a critical section with a Pthreads mutex?

A.`pthread_mutex_unlock(&mutex);` -> Critical Section -> `pthread_mutex_lock(&mutex);`
B.`pthread_mutex_lock(&mutex);` -> Critical Section -> `pthread_mutex_unlock(&mutex);` ✅
C.`pthread_mutex_lock(&mutex);` -> `pthread_mutex_unlock(&mutex);` -> Critical Section
D.Critical Section -> `pthread_mutex_lock(&mutex);` -> `pthread_mutex_unlock(&mutex);`
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The correct sequence is to acquire the lock before entering the critical section and release it after exiting the critical section. This ensures mutual exclusion, guaranteeing that only one thread can execute the critical section code at any time.

Q24. A thread attempts to lock a mutex that is already locked by a different thread. What happens to the state of the first thread?

A.It is immediately destroyed.
B.It spins in a busy-wait loop.
C.It is put to sleep (blocked). ✅
D.It continues execution and ignores the lock.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: `pthread_mutex_lock()` blocks the calling thread until the mutex becomes available. This means the thread is put to sleep and removed from the CPU's run queue. It will not consume CPU time while waiting, which is more efficient than busy-waiting.

Q25. Consider the following code: `sem_t sem; sem_init(&sem, 1, 0);`. What does this code accomplish?

A.Creates a binary semaphore for threads within the same process.
B.Creates a counting semaphore with an initial value of 1.
C.Creates an unnamed semaphore that can be shared by multiple processes. ✅
D.Creates an unnamed semaphore that is initialized to 0.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The second parameter to `sem_init()` is set to 1 (non-zero). This indicates that the semaphore can be shared among multiple processes. The initial value is set to 0. This code creates an inter-process unnamed semaphore. Note: Named semaphores are usually created with `sem_open()`.

Q26. What is a key difference between how a mutex lock and a counting semaphore control access to a resource?

A.A mutex can be used for signaling, while a semaphore cannot.
B.A semaphore can allow multiple concurrent accesses to a resource, while a standard mutex allows only one. ✅
C.A semaphore is faster than a mutex.
D.A mutex is a kernel-level primitive, while a semaphore is user-level.
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: A mutex enforces strict mutual exclusion, allowing only one thread to hold the lock. A counting semaphore, when initialized to a value greater than 1, can allow up to that many concurrent accesses to a resource. While they share similar functions when initialized to 1 (binary semaphore), this distinction in their control over concurrent access is key.

Q27. Which of the following accurately describes the use of condition variables in Pthreads?

A.They are used to protect critical sections.
B.They are used to signal events or changes in state between threads. ✅
C.They are an alternative to mutex locks.
D.They are used to create named semaphores.
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: Condition variables are a synchronization mechanism that allows threads to wait for a specific condition to become true. They are used in conjunction with mutex locks. Their primary purpose is signaling and waiting for state changes, not directly protecting critical sections (mutexes do that).

Q28. What is the purpose of the `NULL` pointer passed as the second argument to `pthread_mutex_init()`?

A.To indicate the mutex should be initialized in a locked state.
B.To indicate the mutex should be in a recursive state.
C.To use the default attribute settings for the mutex. ✅
D.To indicate the mutex is a named mutex.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Passing `NULL` as the second parameter to `pthread_mutex_init()` tells the function to use the default mutex attributes. This is a common pattern in Pthreads functions where attributes can be customized. The mutex will be created with standard, default behavior.

Q29. In the context of Pthreads, if a thread needs to wait for a specific condition to be true, which synchronization primitive should it use?

A.Mutex lock
B.Spinlock
C.Condition variable ✅
D.Read-write lock
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Condition variables are designed for signaling and waiting on state changes. A thread can wait on a condition variable, and another thread can signal it when the condition is met. Mutexes are for mutual exclusion, and read-write locks are for controlling access to shared data with different read/write patterns.

Q30. Which of the following is a correct statement about the portability of Pthreads extensions like spinlocks?

A.They are guaranteed to be portable across all Pthreads implementations.
B.They are not part of the core standard and may have varying implementations. ✅
C.They are only available on Windows systems.
D.They are always slower than mutex locks.
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The text explicitly warns that not all extensions are considered portable from one implementation to another. They are not part of the core Pthreads specification and may be implemented differently or not at all on different platforms. This makes them less portable than the core synchronization primitives.

Q31. A developer wants to use a semaphore to protect a critical section but is unsure about the type to use. What is the correct data type for a POSIX semaphore?

A.mutex_t
B.pthread_mutex_t
C.semaphore_t
D.sem_t ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: The POSIX semaphore API uses the `sem_t` data type for semaphores. `pthread_mutex_t` is for Pthreads mutexes. The other options are not standard data types in the POSIX semaphore or Pthreads APIs.

Q32. Which of the following is NOT a valid parameter for the `pthread_mutex_init()` function?

A.A pointer to the mutex to be initialized
B.The initial value of the mutex ✅
C.An attribute object to customize the mutex
D.NULL to use default attributes
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: `pthread_mutex_init()` takes a pointer to the mutex and an optional attribute object (or NULL). It does not take an 'initial value' parameter because mutexes are either locked or unlocked; their state is binary. The initial value concept applies to semaphores, not mutexes.

Q33. What is the fundamental difference between a mutex lock and a read-write lock?

A.Mutex locks are for kernel-level, read-write locks for user-level.
B.Mutex locks are faster but provide less flexibility.
C.Read-write locks allow multiple concurrent readers, but mutexes only allow one owner at a time. ✅
D.Read-write locks are a superset of mutexes.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Read-write locks provide greater concurrency by allowing multiple threads to hold the lock in read mode simultaneously. Mutexes are simpler and grant exclusive access to a single thread. This distinction is crucial for performance optimization when reads vastly outnumber writes.

Q34. Given that POSIX semaphores are part of the POSIX SEM extension, what is true about their relationship with the Pthreads standard?

A.They are a required part of any valid Pthreads implementation.
B.They are defined in a separate standard and are not required by Pthreads. ✅
C.They are incompatible with Pthreads mutexes.
D.They can only be used with kernel threads.
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The text explicitly states that semaphores are not part of the Pthreads standard and belong to the POSIX SEM extension. This means a system implementing Pthreads is not required to also implement POSIX semaphores, as they are separate specifications.

Q35. Which of the following is a correct statement about the `pthread_mutex_lock()` function?

A.It can only be called by the main thread.
B.It returns immediately if the mutex is already locked.
C.It blocks the calling thread if the mutex is locked by another thread. ✅
D.It is used to initialize the mutex.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: `pthread_mutex_lock()` blocks the calling thread until it can acquire the mutex. This is its fundamental behavior for enforcing mutual exclusion. The calling thread will not return from this function until it has successfully locked the mutex.

Q36. Why might a developer choose a counting semaphore over a mutex for resource management?

A.To protect a critical section of code
B.To allow a limited number of threads to access a resource pool concurrently ✅
C.To simplify the code for thread creation
D.To implement a spinlock for performance
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: A counting semaphore is ideal for managing a pool of identical resources (e.g., a database connection pool) where multiple threads can access the pool up to a certain limit. A mutex would only allow one thread to access the pool at a time, severely limiting concurrency.

Q37. What is the initial value of a mutex lock immediately after a successful call to `pthread_mutex_init()`?

A.0 ✅
B.1
C.NULL
D.-1
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: The mutex is initialized to an unlocked state. In many implementations, an unlocked mutex might be represented internally by a value of 0. The key concept is that it is unlocked and ready to be acquired. The value 1 could be interpreted as locked, so 0 is a logical choice for the initial state.

Q38. Which synchronization primitive would be the most appropriate for a scenario where multiple threads need to read a shared data structure frequently, but writes are rare?

A.Mutex lock
B.Spinlock
C.Condition variable
D.Read-write lock ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: A read-write lock is designed for this exact scenario. It allows many threads to hold the lock concurrently for reading, which maximizes concurrency. When a thread needs to write, it obtains exclusive access. This is more efficient than a mutex, which would serialize all read accesses as well.

Q39. What does a nonzero value in the second parameter of `sem_init()` indicate?

A.An error has occurred during initialization.
B.The semaphore will be initialized to a nonzero value.
C.The semaphore can be shared with other processes. ✅
D.The semaphore is a named semaphore.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: A non-zero value for the 'pshared' flag in `sem_init()` indicates that the semaphore should be shared between processes. If the flag is zero, the semaphore is private to the process that creates it. This parameter controls the visibility and accessibility of the semaphore.

Q40. In the Pthreads API, what is the primary purpose of a mutex lock?

A.To provide a means for threads to signal each other
B.To ensure that only one thread can execute a critical section at a time ✅
C.To allow multiple threads to read shared data concurrently
D.To synchronize operations between unrelated processes
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The primary purpose of a mutex is to enforce mutual exclusion. It guarantees that only one thread can hold the lock at any given time, thereby protecting critical sections of code from concurrent execution. The other options describe other synchronization mechanisms.

Q41. What is the correct header file to include when using POSIX semaphores in a C program?

A.<pthread.h>
B.<semaphore.h> ✅
C.<mutex.h>
D.<stdlib.h>
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The POSIX semaphore functions and data types are defined in the `<semaphore.h>` header file. The `<pthread.h>` header is for the Pthreads API. Including the correct header is essential for the code to compile correctly.

Q42. Consider the code: `pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;`. What is this an example of?

A.Dynamic initialization of a mutex
B.Static initialization of a mutex ✅
C.A compilation error
D.Creating a named mutex
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: `PTHREAD_MUTEX_INITIALIZER` is a macro used for statically initializing a mutex at compile time. This is an alternative to calling `pthread_mutex_init()` at runtime. This approach is often used for global or static mutexes. The text mentions `pthread_mutex_init()`, but this is a common related concept.

Q43. Which of the following is NOT a correct way to initialize a Pthreads mutex?

A.Calling `pthread_mutex_init(&mutex, NULL)`
B.Using the `PTHREAD_MUTEX_INITIALIZER` macro
C.Calling `pthread_mutex_alloc()` and then `pthread_mutex_init()` ✅
D.None of the above
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: `pthread_mutex_init()` is the standard way to initialize a mutex. The `PTHREAD_MUTEX_INITIALIZER` macro can be used for static initialization. There is no standard `pthread_mutex_alloc()` function. Mutexes are usually declared as a variable of type `pthread_mutex_t` and then initialized.

Q44. What happens if a thread calls `pthread_mutex_unlock()` on a mutex that is not locked?

A.A deadlock occurs.
B.The mutex is locked.
C.Undefined behavior. ✅
D.The call is ignored.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Unlocking a mutex that is not locked is a serious error. The behavior is generally considered undefined in the POSIX standard. In practice, it might cause the mutex state to become corrupted or lead to unpredictable errors, making it difficult to debug. It is crucial to ensure only the lock owner unlocks it.

Q45. How does the Pthreads API contribute to the portability of multithreaded applications?

A.By providing a kernel-specific implementation
B.By providing a standardized API at the user level ✅
C.By relying on hardware-specific assembly code
D.By not supporting synchronization primitives
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The Pthreads API is designed to be a standard, portable API for threads at the user level. Since it is not tied to any specific kernel, applications written using Pthreads can be compiled and run on many different operating systems that support the standard, increasing code portability.

Q46. A developer needs to signal a waiting thread that a particular condition has been met. Which mechanism is designed for this purpose?

A.Mutex
B.Spinlock
C.Condition variable ✅
D.Read-write lock
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Condition variables are the synchronization primitive specifically designed for signaling and waiting for condition changes. A thread can wait on a condition variable, and another thread can signal it using `pthread_cond_signal()` or `pthread_cond_broadcast()`, notifying the waiting thread that a condition has changed.

Q47. What are the parameters required by the `sem_init()` function in the correct order?

A.Pointer to semaphore, initial value, sharing flag
B.Sharing flag, pointer to semaphore, initial value
C.Pointer to semaphore, sharing flag, initial value ✅
D.Initial value, pointer to semaphore, sharing flag
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The correct order of parameters for `sem_init()` is: a pointer to the semaphore (sem_t*), a flag (int) indicating the sharing level, and the initial value (unsigned int) for the semaphore. This is explicitly stated in the text. Getting the order wrong would lead to compilation or runtime errors.

Q48. What is a potential issue when using spinlocks, as mentioned in the text?

A.They are always slower than mutexes
B.They are not portable across all implementations ✅
C.They can only be used in single-threaded applications
D.They do not protect critical sections
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: The text explicitly warns that not all Pthreads extensions, such as spinlocks, are portable from one implementation to another. This means code that uses spinlocks might not work correctly or might not even compile on a different system that implements Pthreads differently.

Q49. In the `sem_init(&sem, 0, 1);` code snippet, what is the purpose of the '0' parameter?

A.It indicates that the semaphore is named.
B.It sets the initial value of the semaphore to 0.
C.It restricts the semaphore to threads within the same process. ✅
D.It disables error checking.
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The second parameter (the flag) is set to 0, which restricts sharing. This means the semaphore can only be used by threads belonging to the same process. This is a key point for managing the scope and accessibility of the semaphore.

Q50. What does the term 'critical section' refer to in the context of thread synchronization?

A.A part of the code that creates new threads.
B.A part of the code that uses a condition variable.
C.A part of the code that accesses shared resources.
D.A part of the code that should be executed by a single thread at a time. ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: A critical section is a segment of code that accesses shared resources and must be executed atomically. It is protected by synchronization primitives like mutex locks to prevent race conditions. Mutexes ensure that only one thread can enter a critical section at a time.

Q51. Consider a scenario where a counting semaphore is initialized to 5. How many threads can successfully call `sem_wait()` on this semaphore without blocking?

A.1
B.5 ✅
C.0
D.Unlimited
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: A counting semaphore with an initial value of 5 allows up to 5 threads to successfully decrement it (call `sem_wait()`) without blocking. The sixth thread that attempts to decrement it will see the value at 0 and block until another thread calls `sem_post()` to increment it.

Q52. What is the outcome of a thread calling `pthread_mutex_lock()` and then `pthread_mutex_lock()` again on the same mutex without unlocking it?

A.The thread will deadlock.
B.The thread will be blocked indefinitely. ✅
C.The thread will return an error.
D.The lock count is incremented.
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: This is a classic deadlock scenario. If the mutex is not recursive (which is the default behavior unless explicitly set), the thread will attempt to lock a mutex it already owns. Since the mutex is locked, the thread will block, waiting for itself to unlock it, leading to a permanent deadlock.

Q53. Which of the following best describes the relationship between mutex locks and condition variables in Pthreads?

A.Condition variables can be used without mutex locks.
B.Mutex locks are required to protect the condition variable itself.
C.Condition variables are used to signal changes, while mutexes protect the shared data associated with the condition. ✅
D.They are completely independent and serve different purposes.
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: Condition variables and mutexes work together. A mutex protects the shared data, and the condition variable is used to wait for a change in that data. The mutex must be held when waiting on or signaling a condition variable to prevent race conditions where a signal is missed or a condition change is not seen.

Q54. A developer wants to implement a thread-safe bounded buffer using Pthreads. Which combination of synchronization primitives is most suitable?

A.Only a mutex lock
B.Only a condition variable
C.A mutex lock and two condition variables ✅
D.A read-write lock
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: A bounded buffer (producer-consumer) typically requires a mutex to protect the buffer itself and two condition variables: one for 'not empty' and one for 'not full'. The mutex ensures exclusive access to the buffer, while the condition variables allow threads to wait efficiently for specific buffer states, preventing busy-waiting.

Q55. What is a significant problem if a thread fails to release a mutex lock before terminating?

A.Other threads may be blocked indefinitely. ✅
B.The system will crash.
C.The mutex will be automatically released by the kernel.
D.The program will continue to run without issues.
💡 Difficulty: hard | ✅ Correct: A

📖 Explanation: If a thread holding a mutex terminates without unlocking it, the mutex remains in a locked state. Any other thread attempting to acquire it will be blocked forever. This is a serious bug that leads to a deadlock. This highlights the importance of always ensuring proper lock acquisition and release.

Q56. A developer has two threads that need to coordinate their execution: Thread A must perform a task before Thread B can proceed. Which synchronization primitive is the most appropriate for this scenario?

A.Mutex lock
B.Counting semaphore initialized to 0 ✅
C.Read-write lock
D.Condition variable without a mutex
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: A binary semaphore initialized to 0 is ideal for this signaling scenario. Thread B can call `sem_wait()` on the semaphore, which will block. Thread A, after performing its task, calls `sem_post()` on the semaphore, which unblocks Thread B. This ensures Thread B waits until Thread A completes its task.

Q57. In a Pthreads program, a deadlock occurs because two threads are waiting for each other's mutexes. This is a result of:

A.Incorrect use of condition variables.
B.Mutex locks being acquired in an inconsistent order. ✅
C.A thread attempting to unlock a mutex it does not own.
D.The `pthread_mutex_init()` function failing.
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: Deadlocks commonly occur when multiple threads acquire multiple mutexes in different orders. For example, if Thread A locks Mutex 1 then Mutex 2, and Thread B locks Mutex 2 then Mutex 1, they can each hold one mutex and wait for the other, leading to a deadlock.

Q58. What is the effect of calling `sem_post()` on a semaphore that already has a maximum value?

A.The semaphore value wraps around to zero.
B.The semaphore value remains at the maximum.
C.The call returns an error.
D.The behavior is undefined. ✅
💡 Difficulty: hard | ✅ Correct: D

📖 Explanation: The POSIX standard states that the behavior of `sem_post()` is undefined if it would cause the semaphore's value to exceed `SEM_VALUE_MAX`. This is an overflow condition. While some implementations might cap the value or return an error, relying on either is not portable; the behavior is not defined by the standard.

Q59. Given a system with multiple threads, which design approach minimizes contention and maximizes concurrency?

A.Using a single global mutex for all shared resources.
B.Using fine-grained locking with multiple mutexes for different resources. ✅
C.Using spinlocks for all critical sections.
D.Avoiding the use of condition variables.
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: Fine-grained locking, where separate mutexes protect different resources or parts of a data structure, significantly reduces contention. Instead of threads waiting for a single global lock, they can concurrently access different resources, which greatly improves scalability and overall system performance.

Q60. What is a key advantage of using condition variables over busy-waiting (spinning) for a thread that needs to wait for a condition?

A.Condition variables are easier to implement.
B.Condition variables consume less CPU time. ✅
C.Condition variables are guaranteed to be faster.
D.Condition variables can wait for multiple conditions simultaneously.
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: Condition variables allow a thread to be blocked (put to sleep) while waiting for a condition, which consumes no CPU cycles. Busy-waiting, where a thread repeatedly checks a condition in a loop, wastes CPU cycles that could be used by other threads. This makes condition variables much more efficient for lengthy waits.

Q61. A program uses `pthread_mutex_t` and `pthread_cond_t` variables. What must a thread do before it can safely wait on a condition variable?

A.Acquire the associated mutex. ✅
B.Release the associated mutex.
C.Signal the condition variable.
D.Initialize the condition variable with `pthread_cond_init()`.
💡 Difficulty: hard | ✅ Correct: A

📖 Explanation: To safely wait on a condition variable, a thread must first lock the associated mutex. This ensures that the condition being checked is consistent and prevents race conditions. The thread then atomically releases the mutex and waits on the condition variable, so other threads can modify the shared data.

Q62. Which scenario describes a situation where using a read-write lock would provide a performance benefit over a mutex lock?

A.A shared data structure that is rarely accessed.
B.A shared data structure where both reads and writes are frequent and balanced.
C.A shared data structure where reads are frequent and writes are infrequent. ✅
D.A shared data structure accessed by a single thread.
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: Read-write locks shine when reads are frequent and writes are infrequent. By allowing multiple readers to hold the lock simultaneously, they increase concurrency and reduce waiting times. In contrast, a mutex would serialize all accesses, including the numerous reads, limiting performance.

Q63. If a thread is blocked on a `pthread_mutex_lock()` call, what is its scheduling state?

A.Running
B.Ready
C.Blocked (Waiting) ✅
D.Terminated
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: When a thread calls `pthread_mutex_lock()` and the mutex is already held, it cannot proceed. It is removed from the CPU and placed in a waiting state (blocked). It will remain blocked until the mutex becomes available and the thread is woken up to acquire the lock and be scheduled for execution.

Q64. Given the overhead of synchronization, what is a common strategy to improve performance in multithreaded applications?

A.Use as many mutexes as possible.
B.Avoid synchronization entirely.
C.Use lock-free algorithms where possible. ✅
D.Increase the number of threads.
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: Lock-free algorithms and data structures are designed to operate without traditional locks like mutexes. They use atomic operations to ensure data consistency, which can significantly reduce contention and eliminate problems like deadlocks and priority inversion, making them a very efficient, albeit complex, alternative.

Q65. In a system using POSIX semaphores, what potential issue arises if a process terminates unexpectedly while holding a semaphore?

A.The system will crash.
B.Other processes waiting on the semaphore will be blocked indefinitely.
C.The semaphore will be automatically released by the kernel. ✅
D.The semaphore's value is corrupted.
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: Unlike mutexes which are not automatically released by the kernel (leading to potential deadlock), the POSIX standard specifies that semaphores are system-wide resources. If a process terminates (crashes or is killed), the kernel will automatically clean up its resources, which includes releasing any semaphores it held. This prevents a single process's failure from blocking others.

Q66. What is the primary purpose of the `PTHREAD_MUTEX_INITIALIZER` macro?

A.To dynamically create a mutex at runtime.
B.To statically initialize a mutex at compile time. ✅
C.To set the mutex to a locked state.
D.To define a mutex as recursive.
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: The `PTHREAD_MUTEX_INITIALIZER` is a macro used to statically initialize a mutex. This is typically used for global or static mutexes whose attributes are set to the default. It is an alternative to `pthread_mutex_init()` and is evaluated at compile time, ensuring the mutex is in a known, valid state before the program starts.

🔗 Related Topics (MCQs)