程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Thread and Sync In C# (C#中的線程與同步)

Thread and Sync In C# (C#中的線程與同步)

編輯:關於C語言

Don't belIEve everything they've told you. Threads in C# are actually pretty easy.

 

別相信別人告訴你的所有的事。其實C#中的線程是很簡單的。

 

A thread is an encapsulation of the flow of control in a program. you might be used to writing single-threaded programs - that is, programs that only execute one path through their code "at a time". If you have more than one thread, then code paths run "simultaneously".

 

線程是程序中的控制流程的封裝。你可能已經習慣於寫單線程程序,也就是,程序在它們的代碼中一次只在一條路中執行。如果你多弄幾個線程的話,代碼運行可能會更加“同步”。

 

Why are some phrases above in quotes? In a typical process in which multiple threads exist, zero or more threads may actually be running at any one time. However on a Machine that got n CPU's only one thread (actually) can run at any given time on each CPU, because each thread is a code path, each CPU can only run one code-action at a time. The appearance of running many more than n "simultaneously" is done by sharing the CPUs among threads.

 

在一個有著多線程的典型進程中,零個或更多線程在同時運行。但是,在有著N個CPU的機器上,一個線程只能在給定的時間上在一個CPU上運行,因為每個線程都是一個代碼段,每個CPU一次只能運行一段代碼。而看起來像是N個同時完成是線程間共享CPU時間片的效果。

 

In this example we will create another thread, we will try to implement a way to demonstrate the multithreaded way of working between the two threads we have, and at the end, we will sync the two threads (the main and the new one) for letting the new thread "wait" for a message before continuing.

 

這個例子裡,我們將創建另一個線程,我們將用兩個線程演示多線程的工作方式,最後,我們實現兩個線程(主線程與新線程)同步,在新線程工作前必須等待消息。

 

To create a thread we need to add the System.Threading namespace. After that we need to understand that a thread has GOT to have a start point for its flow of control. The start point is a function, which should be in the same call or in a different one.

 

建立線程前我們必須引入System.Threading命名空間。然後我需要知道的是,線程得為控制流程建立一個起點。起點是一個函數,可以使一個相同的調用或其它。

 

Here you can see a function in the same class that is defined as the start point.

 

這裡你可以看到在同一個類中定義的起點函數。

 

using System;

using System.Threading;

 

namespace ThreadingTester

{

 

 

 

 class ThreadClass

 {

 

   public static void trmain()

   {

   

    for(int x=0;x < 10;x++)

    {

     Thread.Sleep(1000);

     Console.WriteLine(x);

    }

   } 

 

 

   static void Main(string[] args)

   {

 

 

    Thread thrd1=new Thread(new ThreadStart(trmain));

   

    thrd1.Start();

 

    for(int x=0;x < 10;x++)

    {

     Thread.Sleep(900);

     Console.WriteLine("Main    :" + x);

    }

 

   }

 

 }

 

}

 

Thread.Sleep(n) method puts the *this* thread into sleep for n milliseconds. You can see in this example, that in main we define a new thread, which its start point is the function trmain(), we then invoke the Start() method to begin the execution.

 


Thread.Sleep(n)方法把“this”線程置於n毫秒的休眠狀態。你可以看看這個例子,在主函數我們定義了一個新的線程,其中它的起點是函數trmain(),我們然後包含了Start()方法開始執行。

If you run this example, you will know that the context switch between the threads (the process of letting a thread run in the CPU and then switching to another thread) lets the threads run almost together, I have placed the main thread to sleep 100 milliseconds less than the new thread in order to see which one thread runs "faster".

如果你運行這個例子,你就會了解線程間的切換(讓CPU從運行一個線程轉到另一個線程)讓線程幾乎同時運行,為了能看哪個線程運行更快我把主線程設置比新線程少100毫秒。

Now, a thread could be assigned with a name, before Starting the thread we could:

現在,在開始線程前,先給線程命名:

   Thread thrd1=new Thread(new ThreadStart(trmain));

   thrd1.Name="thread1";

   thrd1.Start();

In the thread itself, we can take the name into usage by:

   Thread tr = Thread.CurrentThread;

   Console.WriteLine(tr.Name);

After we made that, imagine that we don’t want the new thread to run to the end immediately when we start it, say we want to start the new thread, let it run, in a certain point the new thread will pause and will wait for a message from the main thread (or from another thread).

在完成上面程序後,設想我們不想在一開始新線程就讓它馬上運行結束,也就是說,我們開啟了一個新線程,讓它運行,在某個特定的時間點,新線程暫停並等待從主線程(或其他線程)發來的消息。


We can do that by defining:

我們可以這樣定義:

   public static ManualResetEvent mre = new ManualResetEvent(false);

The ManualResetEvent is being created with false as start state, this class is being used to signal another thread, and to wait for one or more threads. Note that all threads should have Access to that class in order to signal or listen on the same one.

ManualResetEvent建立時是把false作為start的初始狀態,這個類用於通知另一個線程,讓它等待一個或多個線程。注意,為了通知或監聽同一個線程,所有的其它線程都能訪問那個類。

The waiting thread should:

等待線程這樣寫:

   mre.WaitOne();

This will cause the waiting thread to pause indefinitely and wait for the class to be signaled.

這將引起等待線程無限期的阻塞並等待類來通知。

The signaling thread should:

發信號的線程應該這樣:

   mre.Set();

That will cause the class to be signaled as true, and the waiting thread will stop waiting. After signaling an event we can reset it to the base state by:

這樣類就會被通知,值變成true,等待線程就會停止等待。在通知事件發生後,我們就可以使用下面語句把線程置於基狀態:

   mre.Reset();

Now lets implement all that in a single application:

現在讓我們在程序執行一下:

using System;

using System.Threading;

namespace ThreadingTester

{

 class ThreadClass

 {

  public static ManualResetEvent mre=new ManualResetEvent(false);

   public static void trmain()

   {

    Thread tr = Thread.CurrentThread;

    Console.WriteLine("thread: waiting for an event");

    mre.WaitOne();

    Console.WriteLine("thread: got an event");

    for(int x=0;x < 10;x++)

       {

     Thread.Sleep(1000);

     Console.WriteLine(tr.Name +": " + x);

    }

   } 

   static void Main(string[] args)

   {

    Thread thrd1=new Thread(new ThreadStart(trmain));

    thrd1.Name="thread1";

    thrd1.Start();

    for(int x=0;x < 10;x++)

    {

     Thread.Sleep(900);

     Console.WriteLine("Main    :" + x);

     if(5==x) mre.Set();

    }

    while(thrd1.IsAlive)

    {

     Thread.Sleep(1000);

     Console.WriteLine("Main: waiting for thread to stop...");

    }

   }

 }

}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved