Multithread & Async Development Flashcards

(33 cards)

1
Q

What is a “timeslice”?

A

The CPU Thread Scheduler gives each ready-to-run thread a very small, fixed amount of CPU time, called a “time slice” or “quantum.” When a thread’s time slice expires, the scheduler interrupts it and quickly switches the CPU to another waiting thread. This rapid switching happens so fast (thousands of times per second) that it creates the illusion of concurrent or simultaneous execution, allowing multiple programs and tasks to appear to run at the same time, ensuring fairness and responsiveness across all active applications.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Explain the relationship between the CPU, Thread Scheduler, and Process/Application

A

The Process/Application contains Threads, and these Threads are the units of work that the Thread Scheduler assigns to the CPU for execution

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is “Divide and Conquer” in multi-threading applications, and why is it useful?

A

It is for breaking down problems into multiple smaller, independent sub-problems. Each of these smaller sub-problems can then be assigned to a separate thread to be solved concurrently (at the same time).

Once all the threads complete their individual tasks, their results are combined to produce the final solution to the original large problem.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

what is the below code called and what does it do?

lock(…) { … }

A

It is called an Exclusive Lock.

It creates a critical section of code, meaning it ensures that only one thread can execute the code block within the lock statement at any given time. If another thread tries to enter the same lock block while it’s already locked, that thread will be blocked (paused) until the first thread exits the block and releases the lock.

Its primary purpose is to prevent race conditions and ensure thread safety when multiple threads try to access or modify shared resources (like a shared variable, a list, or a database connection) simultaneously, which could otherwise lead to incorrect or unpredictable results.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What does lock(…) { … } compile to?

A

Monitor.Enter(lockObject);
try
{
// your code here
}
finally
{
Monitor.Exit(lockObject);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Why is Task.Run(() => {}) preferred over new Thread(() => {}).Start()

A

Task.Run(() => {}) leverages the .NET Thread Pool, which is a highly optimized pool of reusable threads managed by the runtime. Task.Run() efficiently reuses existing threads from the thread pool, avoiding the cost of creating new ones.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What are reasons why an application might have multiple processes instead of just one?

A

Security: The isolation between processes acts as a strong security boundary.

Resource Management: It can be easier to monitor and manage resource consumption (CPU, memory) for individual components when they run in separate processes - like how modern browsers work.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

In C#, what is a Mutex, and why use one?

A

A Mutex (Mutual Exclusion) is a synchronization primitive that grants exclusive access to a shared resource to only one thread at a time. Use it to prevent race conditions and ensure thread safety when multiple threads access shared data or resources.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Why use a Mutex over lock/Monitor?

A

Mutexes can be used for inter-process synchronization (across different processes), while lock/Monitor are for intra-process (within the same process) synchronization. Mutexes can also be named system-wide.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What are “Reader” and “Writer” locks?

A

Reader/Writer locks (ReaderWriterLockSlim in C#) allow multiple “reader” threads concurrent access to a resource while granting exclusive access to a single “writer” thread. This optimizes performance when reads far outnumber writes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Why use Reader/Writer locks over lock/Monitor?

A

Reader/Writer locks offer better concurrency than simple locks when there are many more reads than writes. Simple locks (lock/Monitor) block all other threads, even readers, during any access, which can reduce performance in read-heavy scenarios.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How does a Reader/Writer Lock keep the resource synchronized?

A

When a resource is under a reader lock, multiple readers can access it simultaneously. This lock specifically prevents writers from making changes.

In contrast, a writer lock provides exclusive control, meaning no other readers or writers can access the resource until the writer is finished.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is a Semaphore and how do they work?

A

A Semaphore controls access to a limited pool of resources. It maintains a count of available resources. Threads request a resource (decrement count); if unavailable, they wait. When a thread releases a resource (increment count), a waiting thread can acquire it.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is a reason to use the Semaphore?

A

You can release locks in different threads. An example would be: using semaphore.Wait() in one thread, spinning off another thread and allowing the thread that spun off to .Release() the semaphore.

semaphore.Wait()
new Thread(() => someProcess).Start();

void someProcess
{
// do some work
semaphore.Release();
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is Thread Affinity?

A

Thread affinity is the concept where a task or operation prefers or requires execution on a specific thread or a set of threads, often due to reliance on thread-local state or UI components tied to a particular thread.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is the Threads window in Visual Studio and what is it used for?

A

The Threads window in Visual Studio is a debugging tool that lists all active threads in your application. It allows you to inspect each thread’s ID, name, location, priority, and state, as well as switch between threads for focused debugging

16
Q

What is the Parallel Stacks window in Visual Studio and what is it used for?

A

The Parallel Stacks window in Visual Studio is a debugging tool for multithreaded applications. It visually displays call stack information for all threads (or tasks) in the application, helping you understand their relationships, identify deadlocks, and analyze performance issues in parallel code.

17
Q

How can you log the id of the current thread in Visual Studio?

A

Pause the application (this will pause all the threads) and in the Immediate Window, you can write Thread.CurrentThread.ManagedThreadId; and hit enter, and it will log out the current thread that the debugger is focused on.

18
Q

How do you return a result from a thread?

A

With basic threads, the only way to return a result is by using shared variables. Otherwise, you’ll have to use a Task with a TResult.

19
Q

How do call stacks when using multiple threads?

A

Each thread has its own independent call stack. When debugging, you can view the call stack for the currently selected thread in the “Call Stack” window. The “Parallel Stacks” window shows all threads’ call stacks simultaneously.

20
Q

How do you handle exceptions that occur inside a thread?

A

You have to handle the exception inside the thread. If the exception bubbles its way outside the thread, it will break the application regardless if it’s wrapped by a trycatch in the application thread.

21
Q

What is the difference between multi-threaded programming and async programming in c#?

A

Multi-threading uses multiple threads to execute code concurrently and explicitly uses threads.

Though async/await programming uses managed threads behind the scenes, its primary purpose is to perform non-blocking I/O operations, with an emphasis of offloading long long running tasks.

22
Q

What is the difference between a Task and a Thread?

A

A Thread is an OS-level construct representing an execution path. A Task is a higher-level abstraction over an operation that can run asynchronously. Tasks are often executed on a thread pool, abstracting thread management away from the developer.

23
Q

When an exception occurs in a task, what happens to the task and what happens to the application?

A

When an exception occurs in a Task, the exception is stored within the Task itself and the Task transitions to a faulted state. The application generally doesn’t crash immediately unless the exception is explicitly rethrown when the task’s result is accessed or the task is awaited.

24
What is a good practice for handling multiple tasks (that are running in parallel) exceptions?
Create an array of all the tasks, run a Task.WhenAll(), then handle any of the exceptions for any of the tasks in a foreach loop.
25
With Task.WhenAll(), what is tasks.Exception and why important?
tasks.Exception for Task.WhenAll() is an AggregateException. It's important because WhenAll aggregates all exceptions from all faulted tasks into one, allowing you to handle multiple failures comprehensively instead of just the first one. You can get all the exceptions by getting the array of Exceptions from tasks.Exception.InnerExceptions.
26
What does using the .Result automatically do? Excample: var task1 = Task.Run(() => { Thread.Sleep(1000); return 1; }).Result;
Using .Result on a Task automatically blocks the calling thread until the Task completes. If the Task throws an exception, accessing .Result will rethrow that exception (wrapped in an AggregateException)
27
Why does Microsoft recommend CancellationTokenSource for Tasks?
Microsoft recommends CancellationTokenSource for Tasks because it provides a cooperative and standardized mechanism for cancellation. Instead of forcefully terminating threads (which is unsafe), tasks periodically check the token, allowing them to clean up resources and exit gracefully when cancellation is requested. Bonsu: For any CancelationToken exception, they recommend using OperationCanceledException()
28
In any part of the code, what's a way we can see which thread id you are in?
Thread.CurrentThread.ManagedThreadId or Thread.CurrentThread.Name if it has a name.
29
Why use .NET's Parallel Library instead of writing custom threading?
The .NET Parallel Library (TPL) handles thread management, partitioning, load balancing, and exception handling automatically. This simplifies parallel programming, reduces common errors, and optimizes performance across different hardware configurations, saving development time and effort compared to manual threading.
30
31
Are Parallel Loops blocking?
Yes
32