Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interview Question on .NET Threading

Could you describe two methods of synchronizing multi-threaded write access performed on a class member?

Please could any one help me what is this meant to do and what is the right answer.

like image 544
Supremestar Avatar asked Jan 22 '10 13:01

Supremestar


People also ask

What is .NET threading?

With . NET, you can write applications that perform multiple operations at the same time. Operations with the potential of holding up other operations can execute on separate threads, a process known as multithreading or free threading.

What is multithreading in C# Interview Questions?

Answer :A thread is basically a separate sequence of instruction designed to performing a " specific task" in the program. Question 2. What Is Multithreading In C# ? Answer :Performing multiple task at same time during the execution of a program,is known as multithreading.

Is .NET single threaded?

By default, a . NET program is started with a single thread, often called the primary thread. However, it can create additional threads to execute code in parallel or concurrently with the primary thread.

What is difference between task and thread in C#?

Differences Between Task And ThreadThe Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result.


2 Answers

When you change data in C#, something that looks like a single operation may be compiled into several instructions. Take the following class:

public class Number {
    private int a = 0;
    public void Add(int b) {
        a += b;
    }
}

When you build it, you get the following IL code:

IL_0000:  nop
IL_0001:  ldarg.0
IL_0002:  dup
// Pushes the value of the private variable 'a' onto the stack
IL_0003:  ldfld      int32 Simple.Number::a
// Pushes the value of the argument 'b' onto the stack
IL_0008:  ldarg.1
// Adds the top two values of the stack together
IL_0009:  add
// Sets 'a' to the value on top of the stack
IL_000a:  stfld      int32 Simple.Number::a
IL_000f:  ret

Now, say you have a Number object and two threads call its Add method like this:

number.Add(2); // Thread 1
number.Add(3); // Thread 2

If you want the result to be 5 (0 + 2 + 3), there's a problem. You don't know when these threads will execute their instructions. Both threads could execute IL_0003 (pushing zero onto the stack) before either executes IL_000a (actually changing the member variable) and you get this:

a = 0 + 2; // Thread 1
a = 0 + 3; // Thread 2

The last thread to finish 'wins' and at the end of the process, a is 2 or 3 instead of 5.

So you have to make sure that one complete set of instructions finishes before the other set. To do that, you can:

1) Lock access to the class member while it's being written, using one of the many .NET synchronization primitives (like lock, Mutex, ReaderWriterLockSlim, etc.) so that only one thread can work on it at a time.

2) Push write operations into a queue and process that queue with a single thread. As Thorarin points out, you still have to synchronize access to the queue if it isn't thread-safe, but it's worth it for complex write operations.

There are other techniques. Some (like Interlocked) are limited to particular data types, and there are even more (like the ones discussed in Non-blocking synchronization and Part 4 of Joseph Albahari's Threading in C#), though they are more complex: approach them with caution.

like image 176
Jeff Sternal Avatar answered Jan 28 '23 07:01

Jeff Sternal


In multithreaded applications, there are many situations where simultaneous access to the same data can cause problems. In such cases synchronization is required to guarantee that only one thread has access at any one time.

I imagine they mean using the lock-statement (or SyncLock in VB.NET) vs. using a Monitor.

You might want to read this page for examples and an understanding of the concept. However, if you have no experience with multithreaded application design, it will likely become quickly apparent, should your new employer put you to the test. It's a fairly complicated subject, with many possible pitfalls such as deadlock.

There is a decent MSDN page on the subject as well.

There may be other options, depending on the type of member variable and how it is to be changed. Incrementing an integer for example can be done with the Interlocked.Increment method.

As an excercise and demonstration of the problem, try writing an application that starts 5 simultaneous threads, incrementing a shared counter a million times per thread. The intended end result of the counter would be 5 million, but that is (probably) not what you will end up with :)

Edit: made a quick implementation myself (download). Sample output:

Unsynchronized counter demo:
expected counter = 5000000
actual counter   = 4901600
Time taken (ms)  = 67

Synchronized counter demo:
expected counter = 5000000
actual counter   = 5000000
Time taken (ms)  = 287
like image 29
Thorarin Avatar answered Jan 28 '23 06:01

Thorarin