Detailed. Thread Conflicts in net programming

Source: Internet
Author: User
Tags resource static class thread

One, what is a thread conflict

Threading conflict is actually a problem with two or more threads operating on the same shared resource at the same time.

A more classic example is to use a global variable to do the counter, and then open n threads to complete a task, each thread completes a task to add a counter, until the completion of 100 tasks. If you do not consider threading conflicts, using code similar to the following is likely to exceed the task, the more threads, the greater the likelihood of completing the task more than 100 times.

Pseudo code is as follows:

int count = 0;//Global Counter

void Threadmethod ()//method of running on each thread

{

while (true)

{

if (count >= 100)//If the task index is reached

Interrupt thread execution in break;//

DoSomething ()//complete a task

count++;

}

}

Omit code such as the creation of a thread.

Specifically, why do you exceed the task? I don't go into the details here, this example will never exceed the task in a single thread environment.

Of course, in this example, putting count++ in an if statement may reduce the probability of some accidents, but that is not absolute, in other words, such a program can not eliminate the possibility of exceeding the task.

In fact, from the definition of threading conflict, it is not difficult to find that there are two necessary conditions for threading conflict: multithreading and shared resources. If one of these two conditions is not true, there is no thread-conflict problem.

Therefore, in a single-threaded environment, there is no thread-conflict problem. However, unfortunately, our software has evolved to a multithreaded era, single-threaded programs are almost non-existent, whether it is WinForm or WebForm, the program to run the environment is multi-threaded, regardless of whether you have explicitly opened a thread.

Since multithreading is unavoidable, you can only operate from shared resources to avoid threading conflicts.

Second, thread-safe resources

If you often look at the. NET Class Library reference in MSDN or VS Help, it is not hard to find that almost all types have a description of the phrase: "Any public static of this type (Shared in Visual Basic) is thread safe." However, all instance members are not guaranteed to be thread safe. "So what does thread safety mean?"

In fact, thread safety is very simple, that is, a function (methods, properties, fields, or other) at the same time by different threads to use, does not cause any thread conflict problems. Just say this thing is thread safe.

Next, let's talk about what resources are thread-safe.

The term resource is used because thread conflicts occur not only on shared variables, two threads read and write to the same file at the same time, and two programs communicate with the same port at the same time, causing threading conflicts. It's just the operating system and helping us coordinate these conflicts.

A thread-safe resource is the use of resources that do not cause thread-conflict problems in different threads.

A resource that cannot be changed is thread-safe, such as a constant:

Const decimal PAI = 3.14159265;//c++: const double pai = 3.14159265;

Because the value of PAI cannot be changed, using it in a different thread does not create a conflict. In other words it is used in different threads and is used in a thread without distinction, so this thing is thread safe.

Similarly, in. NET, an instance of a string is also thread-safe because an instance of the string is in the. NET can not be changed. Once an instance of a string is created, the results of all of its properties, method invocations, are uniquely determined and will never change. So. NET class Library reference in the string type: "This type is thread safe." ", similar type types, assembly types, are thread-safe.

However, an instance of string is thread-safe, but does not represent a string variable that is thread-safe, in other words, assuming a static variable:

public static string str = "123";

STR is not thread safe, because the string instance of this variable of STR can be modified by any thread.

Consider such an example again:

public static readonly SqlConnection connection = new SqlConnection ("connectionString");

Although connection itself is thread-safe, any member of the connection is not thread-safe.

For example, I called the Open method on this connection in a thread and then made a query operation. But at the same time, another thread called the Close method, and there was an error.

However, there is no thread conflict with code that simply uses connection and does not use any of its members, such as if (connection!= null).

There are still a lot of thread-safe resources here, not to dwell on them.

Read-only fields are thread-safe for members of the. NET Framework's type.

So how do you know if the attributes and methods are thread safe?

Three, thread-safe functions

Because both properties and methods are functions, let's explore what a thread-safe function is.

As we said above, threading conflicts is a prerequisite for multithreading and shared resources. So if a function does not use any resources that might be shared, then it is not possible to thread conflict, which is thread-safe. For example, a function like this:

public static int Add (int a, int b) {

return a + B;

}

All of the resources used in this function are local variables, and the local variables of the function are stored on the stack, each thread has its own stack, so local variables cannot be shared across threads. So this kind of function is obviously thread-safe.

However, it is worth noting that the following functions are not thread-safe:

public static void Swap (ref int A, ref int b)//c++: void Swap (in& A, int& b)

{

int C = A;

A = b;

b = C;

}

Because of the existence of ref, the arguments of a function are passed in by reference, in other words A and b seem to be a local variable of the function, but actually it is something outside the function, and if these two things are the local variables of another function, there is no problem.

If these two things are global variables (static members), there is no guarantee that there is no thread conflict. In the last example, A and B do a copy of the action when the function is passed in, so it doesn't matter whether a or B is a global variable or a static member.

Similarly, such a function is not thread-safe:

public static int Add (Inumber A, inumber b)//c++: int Add (inumber* A, inumber* b);

{

return a.number + b.number;

C + +: return A->number + b->number;

}

The reason is that A and B are the internal variables of the function Yes, but a. Number and B.number are not, they do not exist on the stack, they are on the managed heap, and may be changed by other threads.

But functions that use only local variables are in the. NET class library, but there are so many thread-safe functions in the. NET class library.

Because even if a function uses shared resources, the function is thread-safe if the shared resource it uses is thread-safe.

For example, a function like this:

Private Const string connectionString = "...";p ublic string getconnectionstring ()

{

return connectionString;

}

Although this function uses a shared resource ConnectionString, this function is thread-safe because the resource is thread-safe.

Similarly, we can conclude that if a function calls only thread-safe functions and uses only thread-safe shared resources, then this function is also thread-safe.

Here's an easy to ignore problem, operator. Not all operators, especially the overloaded operators, are thread-safe.

Iv. Mutual-exclusion locks

Sometimes we have to face the problem of thread insecurity, for example, in the beginning of the example, multithreading to complete 100 tasks, how can we solve this problem, a simple way is to give shared resources with mutex. This is simple in C #. For example, the first example:

public static class Environment{public static int count = 0;//Global Counter

}

... void Threadmethod ()//method of running on each thread

{

while (true)

{

Lock (typeof (Environment))

{

if (count >= 100)//If the task index is reached

Interrupt thread execution in break;//

DoSomething ()//complete a task

count++}}}

By mutual exclusion locks, a thread is blocked waiting when the Count field is used, and all other threads are not available. Achieves the effect of avoiding threading conflicts.

Of course, such a lock would make this multithreaded routine degenerate into a single thread running at the same time, so we could put the count++ forward and make the lock range smaller, like this:

void Threadmethod ()//method of running on each thread {

while (true)

{

Lock (typeof (Environment))

{

if (count++ >= 100)//If the task index is reached

Interrupt thread execution in break;//

}

DoSomething ()//complete a task

}}

Finally, let's talk about SyncRoot's problem.

With. NET must be a lot of friends confused, why the lock on a container, you need to write:

Lock (Container.syncroot)

Rather than direct lock (Container)

Because locking a container does not guarantee that the container will not be modified, consider such a container:

public class collection{

Private ArrayList _list;

Public Add (Object item)

{

_list. ADD (item);

}

public object this[int index]

{

get {return _list[index];} set {_list[index] = value;}

}}

It looks like it's all right when you lock it up, no one can modify the container, but in fact the container is just a ArrayList instance, and if a piece of code bypasses the container and operates directly on _list, For this container object lock is also impossible to ensure that the container is not modified.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.