Softenant
Technologies
Python Multithreading MCQs (25) — Answers at the End

Python Multithreading MCQs (25)

Python Training in Vizag (Softenant)

1) Creating and starting a thread

import threading
def work(): print("hi")
t = threading.Thread(target=work)
t.start(); t.join()
A. Prints nothing
B. Prints “hi” once
C. Error: target must be str
D. Prints “hi” twice

2) Daemon thread behavior at process exit

import threading, time
def w(): time.sleep(1); print("done")
t = threading.Thread(target=w, daemon=True)
t.start(); print("end")
A. Always prints “done” then “end”
B. Might skip “done” if main exits first
C. Blocks until “done”
D. Error

3) The GIL implies…

A. Threads can’t run on Windows
B. CPU-bound Python bytecode doesn’t run in true parallel across cores
C. I/O-bound programs never benefit from threads
D. Only one process per machine

4) I/O-bound speedup

# Many blocking network calls
# Using threads vs sequential
A. Threads often speed it up
B. Threads always slow it down
C. No effect possible
D. Only asyncio helps

5) Passing arguments to target

def f(a, b=0): print(a+b)
t = threading.Thread(target=f, args=(2,), kwargs={'b':3})
t.start(); t.join()
A. Prints 2
B. Prints 3
C. Prints 5
D. TypeError

6) Race condition without a lock

x = 0
def add():
    global x
    for _ in range(1000):
        x += 1
A. Always ends at 1000
B. Always ends at 2000
C. Final value is nondeterministic
D. Raises

7) Using a Lock

lock = threading.Lock()
with lock:
    # critical section
    pass
A. Equivalent to lock.acquire()/release()
B. Deadlocks by default
C. No effect
D. SyntaxError

8) Re-entrant lock (RLock)

r = threading.RLock()
def g():
    with r:
        with r:
            return "ok"
print(g())
A. Deadlocks
B. ok
C. Error
D. None

9) Semaphore use

sem = threading.Semaphore(2)
# Allows at most __ simultaneous entrants
A. 1
B. 2
C. 0
D. Unlimited

10) Event for signaling

e = threading.Event()
def waiter():
    e.wait(); print("go")
def setter():
    e.set()
A. wait() returns only False
B. set() releases waiters
C. set() blocks
D. wait() raises

11) Condition: notify vs wait

cond = threading.Condition()
with cond:
    cond.notify()
A. Not allowed inside with
B. Must hold the lock; wakes a waiter
C. Wakes all waiters only
D. Calls wait()

12) Queue is thread-safe

from queue import Queue
q = Queue()
# multiple producers/consumers safely use q.put / q.get
A. False
B. True
C. Only on Linux
D. Only single-threaded

13) Thread identity

import threading
print(threading.current_thread().name)
A. Always “Thread-1”
B. Name of current thread
C. Process name
D. PID

14) Checking liveness

t = threading.Thread(target=lambda: None)
t.start()
print(t.is_alive())
A. Always False
B. True during run, False after finish
C. Always True
D. Raises

15) Join with timeout

t.join(0.1)
if t.is_alive(): print("still running")
A. join(0.1) always blocks until finish
B. After timeout it returns; thread may still run
C. Kills the thread
D. Raises TimeoutError

16) Deadlock possibility

# Two locks acquired in different orders by two threads
# This situation can cause...
A. Starvation only
B. Deadlock
C. Nothing; Python prevents it
D. Compile error

17) Thread-safe counter pattern

lock = threading.Lock()
count = 0
def inc():
    global count
    with lock:
        count += 1
A. Safe against races
B. Still races
C. Deadlocks
D. Slower than GIL

18) ThreadPoolExecutor

from concurrent.futures import ThreadPoolExecutor
def w(x): return x*x
with ThreadPoolExecutor(max_workers=2) as ex:
    futs = [ex.submit(w, i) for i in (2,3)]
    print([f.result() for f in futs])
A. [4, 9]
B. Error
C. [2, 3]
D. None

19) Thread-local storage

local = threading.local()
local.x = 1
# Another thread sees local.x as...
A. Same 1
B. Independent (AttributeError until set)
C. Process-wide shared
D. Random

20) Timer

t = threading.Timer(0.2, lambda: print("tick"))
t.start(); t.join()
A. Prints immediately
B. Prints after ~0.2s
C. Never prints
D. TypeError

21) active_count / enumerate

print(threading.active_count() >= 1)
A. Always True (at least the main thread)
B. Always False
C. Only True on Linux
D. Raises

22) Acquire with timeout

lock = threading.Lock()
ok = lock.acquire(timeout=0.01)
if ok: lock.release()
A. acquire() has no timeout
B. Returns True if acquired in time
C. Raises TimeoutError
D. Deadlocks

23) CPU-bound work recommendation

A. Use more threads to use all cores
B. Prefer multiprocessing or native extensions
C. Sleep more
D. Use Event

24) Printing safely from many threads

# Best practice:
# A) print() directly from all threads
# B) Use a Queue; one printer thread consumes
A. A
B. B
C. Either; same ordering
D. None

25) Setting thread name

t = threading.Thread(target=lambda: None, name="worker-1")
t.start(); print(t.name)
A. worker-1
Thread-1
C. main
D. PID

Answer Key

1) B

2) B

3) B

4) A

5) C

6) C

7) A

8) B

9) B

10) B

11) B

12) B

13) B

14) B

15) B

16) B

17) A

18) A

19) B

20) B

21) A

22) B

23) B

24) B

25) A