Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Creation of C # thread and case analysis of life cycle

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "the creation of C# thread and life cycle instance analysis". In the operation of actual cases, many people will encounter such a dilemma. Next, let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Get the current thread information

Thread.CurrentThread is a static Thread class. The CurrentThread property of Thread can get some information about the current running thread, which is defined as follows:

Public static System.Threading.Thread CurrentThread {get;}

The Thread class has many properties and methods, which will not be listed here. Later studies will gradually familiarize you with more API and learn more about how to use it.

Here is a simple example:

Static void Main (string [] args) {Thread thread = new Thread (OneTest); thread.Name = "Test"; thread.Start (); Console.ReadKey ();} public static void OneTest () {Thread thisTHread = Thread.CurrentThread; Console.WriteLine ("Thread ID:" + thisTHread.Name) Console.WriteLine ("current region:" + thisTHread.CurrentCulture.Name); / / current region Console.WriteLine ("Thread execution status:" + thisTHread.IsAlive); Console.WriteLine ("background thread:" + thisTHread.IsBackground); Console.WriteLine ("Thread pool thread" + thisTHread.IsThreadPoolThread);}

Output

Thread ID: Test current region: zh-CN thread execution status: whether True is a background thread: whether False is a thread pool thread False2, manage thread status

It is generally believed that a thread has five states:

New (new object), ready (waiting for CPU scheduling), running (CPU is running), blocking (waiting for blocking, synchronous blocking, etc.), death (object release).

Don't say too much about the theory, just play with the code.

2.1 Startup and parameter transfer

The new thread is almost familiar with nothing more than new and then Start ().

Thread thread = new Thread ()

There are four constructors for Thread:

Public Thread (ParameterizedThreadStart start); public Thread (ThreadStart start); public Thread (ParameterizedThreadStart start, int maxStackSize); public Thread (ThreadStart start, int maxStackSize)

Let's take the example of passing parameters when starting a new thread. What about using these four constructors?

2.1.1 ParameterizedThreadStart

ParameterizedThreadStart is a delegate, and the constructor passes parameters to the method that needs to be executed, and then passes the parameters in the Start method.

It is important to note that the parameter type passed is object, and only one can be passed.

The code example is as follows:

Static void Main (string [] args) {string myParam = "abcdef"; ParameterizedThreadStart parameterized = new ParameterizedThreadStart (OneTest); Thread thread = new Thread (parameterized); thread.Start (myParam); Console.ReadKey ();} public static void OneTest (object obj) {string str = obj as string If (string.IsNullOrEmpty (str)) return; Console.WriteLine ("New thread has started"); Console.WriteLine (str);} 2.1.2 use static or class member variables

This method does not need to be passed as a parameter, and each thread shares the stack.

The advantage is that there is no need for packing and unpacking, and multi-threads can share space; the disadvantage is that variables can be accessed by everyone, which may lead to a variety of problems (which can be solved by locking) in multithreaded bidding.

The following two variables are used for data transfer:

Class Program {private string A = "member variable"; public static string B = "static variable"; static void Main (string [] args) {/ / create a class Program p = new Program (); Thread thread1 = new Thread (p.OneTest1); thread1.Name = "Test1"; thread1.Start () Thread thread2 = new Thread (OneTest2); thread2.Name = "Test2"; thread2.Start (); Console.ReadKey ();} public void OneTest1 () {Console.WriteLine ("New thread already started"); Console.WriteLine (A) / / other members of its own object} public static void OneTest2 () {Console.WriteLine ("New thread has started"); Console.WriteLine (B); / / Global static variable}} 2.1.3 delegate and Lambda

The principle is that the constructor public Thread (ThreadStart start) of Thread; ThreadStart is a delegate and is defined as follows

Public delegate void ThreadStart ()

If you use a delegate, you can write like this

Static void Main (string [] args) {System.Threading.ThreadStart start = DelegateThread; Thread thread = new Thread (start); thread.Name = "Test"; thread.Start (); Console.ReadKey ();} public static void DelegateThread () {OneTest ("a", "b", 666, new Program ()) } public static void OneTest (string a, string b, int c, Program p) {Console.WriteLine ("new thread already started");}

It's a little bit of a hassle, but we can do it quickly using Lambda.

An example of using Lambda is as follows:

Static void Main (string [] args) {Thread thread = new Thread (() = > {OneTest ("a", "b", 666, new Program ();}); thread.Name = "Test"; thread.Start (); Console.ReadKey () } public static void OneTest (string a, string b, int c, Program p) {Console.WriteLine ("new thread already started");}

Tip: if the algorithm you need to deal with is relatively simple, you can write it directly into the delegate, without the need to write another method.

You can see how convenient C # is.

2.2 pause and blocking

The Thread.Sleep () method can suspend the current thread for a period of time, and the Thread.Join () method can block the current thread from waiting for another thread to run to the end.

While waiting for the thread Sleep () or Join (), the thread is Blocket.

Definition of blocking: when a thread pauses execution for characteristic reasons, it is blocked.

If the thread is in a blocking state, the thread will hand over its CPU time slice and will not consume CPU time until the blocking ends.

Blocking causes a context switch.

The code example is as follows:

Static void Main (string [] args) {Thread thread = new Thread (OneTest); thread.Name = "little brother"; Console.WriteLine ($"{DateTime.Now}: people are having a meal, take their little brother shopping after dinner"); Console.WriteLine ("dinner is over"); Console.WriteLine ($"{DateTime.Now}: little brother starts playing games") Thread.Start (); / / make-up 5 s Console.WriteLine ("regardless of him, big sister makeup first"); Thread.Sleep (TimeSpan.FromSeconds (5)); Console.WriteLine ($"{DateTime.Now}: finish your makeup and wait for your little brother to play the game"); thread.Join (); Console.WriteLine ("have you finished playing the game?" + (! thread.IsAlive? "true": "false"); Console.WriteLine ($"{DateTime.Now}: go shopping"); Console.ReadKey ();} public static void OneTest () {Console.WriteLine (Thread.CurrentThread.Name + "start playing games"); for (int I = 0; I

< 10; i++) { Console.WriteLine($"{DateTime.Now}:第几局:" + i); Thread.Sleep(TimeSpan.FromSeconds(2)); // 休眠 2 秒 } Console.WriteLine(Thread.CurrentThread.Name + "打完了"); } Join() 也可以实现简单的线程同步,即一个线程等待另一个线程完成。 2.3 线程状态 ThreadState 是一个枚举,记录了线程的状态,我们可以从中判断线程的生命周期和健康情况。 其枚举如下: 枚举值说明Initialized0此状态指示线程已初始化但尚未启动。Ready1此状态指示线程因无可用的处理器而等待使用处理器。 线程准备在下一个可用的处理器上运行。Running2此状态指示线程当前正在使用处理器。Standby3此状态指示线程将要使用处理器。 一次只能有一个线程处于此状态。Terminated4此状态指示线程已完成执行并已退出。Transition6此状态指示线程在可以执行前等待处理器之外的资源。 例如,它可能正在等待其执行堆栈从磁盘中分页。Unknown7线程的状态未知。Wait5此状态指示线程尚未准备好使用处理器,因为它正在等待外围操作完成或等待资源释放。 当线程就绪后,将对其进行重排。 但是里面有很多枚举类型是没有用处的,我们可以使用一个这样的方法来获取更加有用的信息: public static ThreadState GetThreadState(ThreadState ts) { return ts & (ThreadState.Unstarted | ThreadState.WaitSleepJoin | ThreadState.Stopped); } 根据 2.2 中的示例,我们修改一下 Main 中的方法: static void Main(string[] args) { Thread thread = new Thread(OneTest); thread.Name = "小弟弟"; Console.WriteLine($"{DateTime.Now}:大家在吃饭,吃完饭后要带小弟弟逛街"); Console.WriteLine("吃完饭了"); Console.WriteLine($"{DateTime.Now}:小弟弟开始玩游戏"); Console.WriteLine("弟弟在干嘛?(线程状态):" + Enum.GetName(typeof(ThreadState), GetThreadState(thread.ThreadState))); thread.Start(); Console.WriteLine("弟弟在干嘛?(线程状态):" + Enum.GetName(typeof(ThreadState), GetThreadState(thread.ThreadState))); // 化妆 5 s Console.WriteLine("不管他,大姐姐化妆先"); Thread.Sleep(TimeSpan.FromSeconds(5)); Console.WriteLine("弟弟在干嘛?(线程状态):" + Enum.GetName(typeof(ThreadState), GetThreadState(thread.ThreadState))); Console.WriteLine($"{DateTime.Now}:化完妆,等小弟弟打完游戏"); thread.Join(); Console.WriteLine("弟弟在干嘛?(线程状态):" + Enum.GetName(typeof(ThreadState), GetThreadState(thread.ThreadState))); Console.WriteLine("打完游戏了嘛?" + (!thread.IsAlive ? "true" : "false")); Console.WriteLine($"{DateTime.Now}:走,逛街去"); Console.ReadKey(); } 代码看着比较乱,请复制到项目中运行一下。 输出示例: 2020/4/11 11:01:48:大家在吃饭,吃完饭后要带小弟弟逛街吃完饭了2020/4/11 11:01:48:小弟弟开始玩游戏弟弟在干嘛?(线程状态):Unstarted弟弟在干嘛?(线程状态):Running不管他,大姐姐化妆先小弟弟开始打游戏2020/4/11 11:01:48:第几局:02020/4/11 11:01:50:第几局:12020/4/11 11:01:52:第几局:2弟弟在干嘛?(线程状态):WaitSleepJoin2020/4/11 11:01:53:化完妆,等小弟弟打完游戏2020/4/11 11:01:54:第几局:32020/4/11 11:01:56:第几局:42020/4/11 11:01:58:第几局:52020/4/11 11:02:00:第几局:62020/4/11 11:02:02:第几局:72020/4/11 11:02:04:第几局:82020/4/11 11:02:06:第几局:9小弟弟打完了弟弟在干嘛?(线程状态):Stopped打完游戏了嘛?true2020/4/11 11:02:08:走,逛街去 可以看到 Unstarted、WaitSleepJoin、Running、Stopped四种状态,即未开始(就绪)、阻塞、运行中、死亡。 2.4 终止 .Abort() 方法不能在 .NET Core 上使用,不然会出现 System.PlatformNotSupportedException:"Thread abort is not supported on this platform." 。 后面关于异步的文章会讲解如何实现终止。 由于 .NET Core 不支持,就不理会这两个方法了。这里只列出 API,不做示例。 方法说明Abort()在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。Abort(Object)引发在其上调用的线程中的 ThreadAbortException以开始处理终止线程,同时提供有关线程终止的异常信息。 调用此方法通常会终止线程。 Abort() 方法给线程注入 ThreadAbortException 异常,导致程序被终止。但是不一定可以终止线程。 2.5 线程的不确定性 线程的不确定性是指几个并行运行的线程,不确定在下一刻 CPU 时间片会分配给谁(当然,分配有优先级)。 对我们来说,多线程是同时运行的,但一般 CPU 没有那么多核,不可能在同一时刻执行所有的线程。CPU 会决定某个时刻将时间片分配给多个线程中的一个线程,这就出现了 CPU 的时间片分配调度。 执行下面的代码示例,你可以看到,两个线程打印的顺序是不确定的,而且每次运行结果都不同。 CPU 有一套公式确定下一次时间片分配给谁,但是比较复杂,需要学习计算机组成原理和操作系统。 留着下次写文章再讲。 static void Main(string[] args) { Thread thread1 = new Thread(Test1); Thread thread2 = new Thread(Test2); thread1.Start(); thread2.Start(); Console.ReadKey(); } public static void Test1() { for (int i = 0; i < 10; i++) { Console.WriteLine("Test1:" + i); } } public static void Test2() { for (int i = 0; i < 10; i++) { Console.WriteLine("Test2:" + i); } }2.6 线程优先级、前台线程和后台线程 Thread.Priority 属性用于设置线程的优先级,Priority 是一个 ThreadPriority 枚举,其枚举类型如下 枚举值说明AboveNormal3可以将 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。BelowNormal1可以将 Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。Highest4可以将 Thread 安排在具有任何其他优先级的线程之前。Lowest0可以将 Thread 安排在具有任何其他优先级的线程之后。Normal2可以将 Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。 默认情况下,线程具有 Normal 优先级。 优先级排序:Highest >

AboveNormal > Normal > BelowNormal > Lowest.

Thread.IsBackgroundThread can set whether the thread is a background thread.

The foreground thread has a higher priority than the background thread, and the program needs to wait for all foreground threads to finish execution before it can be closed; when the program is closed, it will be forced to exit regardless of whether the background thread is executing or not.

2.7 spin and dormancy

Context switching occurs when a thread goes into sleep or is released from sleep, which leads to expensive consumption.

If the thread runs continuously, it will consume CPU time and CPU resources.

For short waits, the spin method should be used to avoid context switching; excessively long waits should cause threads to sleep and avoid taking up a lot of CPU time.

We can sleep the thread using the best-known Sleep () method. There are many types of synchronous threads, and hibernation is also used to wait for threads (drafts have been written).

Spin means asking for trouble.

For example:

Public static void Test (int n) {int num = 0; for (int item0)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report