C# Multithread Foundation

Recently, I wrote a small crawler, which used multi-threading technology, suddenly found that this technology was somewhat strange, so I started to ask Du Niang crazily, and record it here, so that I and your small partners can learn.

I. What is Thread

An application is equivalent to a process. The process has all the resource processes of the application, including threads. The resources of the process are shared by threads, but not threads. We can turn on the task manager in the computer, running. exe is a process, the branches of which are threads.

II. Multithreading

Multithreading is actually a piece of code that runs in parallel in a process.

1. Create and start threads

 1         static void Main()
 2         {
 3             //Getting threads Id
 4             var threadId = Thread.CurrentThread.ManagedThreadId;
 5             var thread = new Thread(Test1);
 6             thread.Start();
 7 
 8             Console.WriteLine(threadId + "_Main()");
 9             Console.Read();
10         }
11 
12         /// <summary>
13         /// test method
14         /// </summary>
15         private static void Test1()
16         {
17             //Getting threads Id
18             var threadId = Thread.CurrentThread.ManagedThreadId;
19             Console.WriteLine(threadId + "_Test()");
20             for (int i = 0; i < 10; i++)
21             {
22                 Console.WriteLine(threadId + "_" + i);
23             }
24         }

Result:

 

 

2. Tentative Nogan Time of Threads

 1         static void Main()
 2         {
 3             //Getting threads Id
 4             var threadId = Thread.CurrentThread.ManagedThreadId;
 5             var thread = new Thread(Test1);
 6             thread.Start();
 7             Console.WriteLine($"Main thread Id{threadId}_Main()");
 8             Console.Read();
 9         }
10 
11         /// <summary>
12         /// test method
13         /// </summary>
14         private static void Test1()
15         {
16             //Getting threads Id
17             var threadId = Thread.CurrentThread.ManagedThreadId;
18             Console.WriteLine($"Cothread Id{threadId}_Test()");
19             for (int i = 0; i < 10; i++)
20             {
21                 Thread.Sleep(1000);//Unit milliseconds
22                 Console.WriteLine($"Cothread Id{threadId}_{DateTime.Now}");
23             }
24         }

Result:

 

 

3. Thread merging

The Thread.Join operation blocks the current thread and waits for the sub-thread to complete before it runs.

 1         static void Main()
 2         {
 3             //Getting threads Id
 4             var threadId = Thread.CurrentThread.ManagedThreadId;
 5             var thread = new Thread(Test1);
 6             thread.Start();
 7             Console.WriteLine($"Main thread Id{threadId}_Main()1");
 8             thread.Join();
 9             Console.WriteLine($"Main thread Id{threadId}_Main()2");
10             Console.Read();
11         }
12 
13         /// <summary>
14         /// test method
15         /// </summary>
16         private static void Test1()
17         {
18             //Getting threads Id
19             var threadId = Thread.CurrentThread.ManagedThreadId;
20             Console.WriteLine($"Cothread Id{threadId}_Test()");
21             for (int i = 0; i < 10; i++)
22             {
23                 Thread.Sleep(1000);//Unit milliseconds
24                 Console.WriteLine($"Cothread Id{threadId}_{DateTime.Now}");
25             }
26         }

Result:

 

 

4. Thread termination

 1         static void Main()
 2         {
 3             //Getting threads Id
 4             var threadId = Thread.CurrentThread.ManagedThreadId;
 5             var thread = new Thread(Test1);
 6             thread.Start();
 7             Console.WriteLine($"Main thread Id{threadId}_Main()1");
 8             Thread.Sleep(3000);
 9            thread.Abort();
10             Console.WriteLine($"Main thread Id{threadId}_Main()2");
11             Console.Read();
12         }
13 
14         /// <summary>
15         /// test method
16         /// </summary>
17         private static void Test1()
18         {
19             //Getting threads Id
20             var threadId = Thread.CurrentThread.ManagedThreadId;
21             Console.WriteLine($"Cothread Id{threadId}_Test()");
22             for (int i = 0; i < 10; i++)
23             {
24                 Thread.Sleep(1000);//Unit milliseconds
25                 Console.WriteLine($"Cothread Id{threadId}_{DateTime.Now}");
26             }
27         }

Result:

5. Parametric Passing in Threads

 1 static void Main()
 2         {
 3             //Getting threads Id
 4             var threadId = Thread.CurrentThread.ManagedThreadId;
 5             Console.WriteLine($"Main thread Id{threadId}_Main()");
 6             //The first way of parameter transfer
 7             var thread1 = new Thread(() => Test1("Little Devil"));
 8             thread1.Start();
 9 
10             //The second way of parameter transfer(The parameter can only be one. object type)
11             var parameterizedThreadStart = new ParameterizedThreadStart(Test2);
12             var thread2 = new Thread(parameterizedThreadStart);
13             thread2.Start("The Great Devil");
14             Console.Read();
15         }
16 
17         /// <summary>
18         /// test method
19         /// </summary>
20         private static void Test1(string name)
21         {
22             //Getting threads Id
23             var threadId = Thread.CurrentThread.ManagedThreadId;
24             Console.WriteLine($"Cothread Id{threadId}_My name is:{name}");
25         }
26 
27         /// <summary>
28         /// test method
29         /// </summary>
30         private static void Test2(object name)
31         {
32             //Getting threads Id
33             var threadId = Thread.CurrentThread.ManagedThreadId;
34             Console.WriteLine($"Cothread Id{threadId}_My name is:{name}");
35         }

Result:

 

 

There are other modes of transmission, which are not explained here, but only introduced by Thread.

6. Thread Safety and Thread Lock

Thread security means that when multithreaded access, lock mechanism is adopted. When a thread accesses some data of this class, it protects it. Other threads can not access it until the thread has finished reading, other threads can not use it. In the case of thread security, there will be no data inconsistency or data contamination. Thread insecurity is not to provide data access protection, there may be multiple threads change the data one after another, resulting in dirty data! Generally speaking, the global variable is thread-safe if there are only read operations and no write operations for global variables and static variables in each thread; if multiple threads perform write operations at the same time, thread synchronization is generally considered, otherwise thread security may be affected.

The lock keyword marks the statement block as a critical area by acquiring the mutex of the specified object, executes the statement and releases the lock.

Lock ensures that when one thread is in the critical zone of the code, the other thread does not enter the critical zone. If other threads try to enter locked code, it will wait (that is, blocked) until the object is released. Using Lock will result in the serialization of the whole application, reduce the concurrency ability of the program and affect the performance.

In what scenario, lock is used to ensure thread safety: the serial is serial and the parallel is parallel.

Before locking:

 1  public static int i = 1000000;
 2         static void Main()
 3         {
 4             //Getting threads Id
 5             var threadId = Thread.CurrentThread.ManagedThreadId;
 6             for (int j = 0; j < 2; j++)
 7             {
 8                 var thread = new Thread(Test1);
 9                 thread.Start();
10             }
11             Console.Read();
12         }
13 
14         /// <summary>
15         /// test method
16         /// </summary>
17         private static void Test1()
18         {
19             //Getting threads Id
20             var threadId = Thread.CurrentThread.ManagedThreadId;
21            
22             Console.WriteLine($"Cothread Id{threadId}_i Initial value:{i}");
23             int count = 0;
24             for (int j = 0; j < 1000000; j++)
25             {
26                 i--;
27                 count++;
28             }
29             Console.WriteLine($"Cothread Id{threadId}_Number of runs:{count}");
30             Console.WriteLine($"Cothread Id{threadId}_i End value:{i}");
31         }

Result:

 

 

 

After locking:

 1  public static int i = 1000000;
 2         private readonly static object objLock = new object();
 3         static void Main()
 4         {
 5             //Getting threads Id
 6             var threadId = Thread.CurrentThread.ManagedThreadId;
 7             for (int j = 0; j < 2; j++)
 8             {
 9                 var thread = new Thread(Test1);
10                 thread.Start();
11             }
12             Console.Read();
13         }
14 
15         private static void Test1()
16         {
17             //Getting threads Id
18             var threadId = Thread.CurrentThread.ManagedThreadId;
19            
20             int count = 0;
21             lock (objLock)
22             {
23                 Console.WriteLine($"Cothread Id{threadId}_i Initial value:{i}");
24                 for (int j = 0; j < 1000000; j++)
25                 {
26                     i--;
27                     count++;
28                 }
29             }
30             Console.WriteLine($"Cothread Id{threadId}_Number of runs:{count}");
31             Console.WriteLine($"Cothread Id{threadId}_i End value:{i}");
32         }

Result:

 

Well, today's knowledge about threads is sub-boxed here.

Keywords: C#

Added by uknowho008 on Mon, 02 Sep 2019 14:39:16 +0300