Thread and Sync In 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...");

    }

   }

 }

}

 

时间: 2024-10-29 23:50:18

Thread and Sync In C# (C#中的线程与同步)的相关文章

线程-C#用Task代替Thread查找文本文件,在Task中如何处理文件锁定的问题呢?

问题描述 C#用Task代替Thread查找文本文件,在Task中如何处理文件锁定的问题呢? C#用Task代替Thread查找文本文件,在Task中如何处理文件锁定的问题呢? 解决方案 对文件读取做同步,一次性读取一块到内存,各自在内存中查找. 解决方案二: 锁定了等待处理完毕啊!你的锁定是什么意思

Java中的线程Thread总结

首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Thread类也实现了Runnable接口,因此,从Thread类继承的类的实例也可以作为target传入这个构造方法.可通过这种方法实现多个线程的资源共享. 线程的生命周期: 1.新建状态(New):用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 2.就绪状态

Java基础-创建Java程序中的线程池

程序|创建 线程是Java的一大特性,它可以是给定的指令序列.给定的方法中定义的变量或者一些共享数据(类一级的变量).在Java中每个线程有自己的堆栈和程序计数器(PC),其中堆栈是用来跟踪线程的上下文(上下文是当线程执行到某处时,当前的局部变量的值),而程序计数器则用来跟踪当前线程正在执行的指令. 在通常情况下,一个线程不能访问另外一个线程的堆栈变量,而且这个线程必须处于如下状态之一: 1.排队状态(Ready),在用户创建了一个线程以后,这个线程不会立即运行.当线程中的方法start()被调

Java开发中的线程安全选择与Swing[Z]

安全 Swing API的设计目标是强大.灵活和易用.特别地,我们希望能让程序员们方便地建立新的Swing组件,不论是从头开始还是通过扩展我们所提供的一些组件. 出于这个目的,我们不要求Swing组件支持多线程访问.相反,我们向组件发送请求并在单一线程中执行请求. 本文讨论线程和Swing组件.目的不仅是为了帮助你以线程安全的方式使用Swing API,而且解释了我们为什么会选择现在这样的线程方案. 本文包括以下内容: 单线程规则:Swing线程在同一时刻仅能被一个线程所访问.一般来说,这个线程

Excel开发中与线程相关的几个问题

采用VSTO或者Shared Add-in等技术开发Excel插件,其实是在与Excel提供的API在打交道,Excel本身的组件大多数都是COM组件,也就是说通过Excel PIA来与COM进行交互.这其中会存在一些问题,这些问题如果处理不好,通常会导致在运行的时候会抛出难以调试的COM异常,从而导致我们开发出的Excel插件的不稳定. 和普通的WinForm程序一样,Excel也是一种STA(Single Thread Apartment)线程的应用程序,Excel插件是寄宿在Excel中运

java中的线程

编写具有多线程能力的程序经常会用到的方法有: run(),start(),wait(),notify(),notifyAll(),sleep(),yield(),join() 还有一个重要的关键字:synchronized 本文将对以上内容进行讲解. 一:run()和start() 示例1: public class threadtest extends thread{public void run(){for(int i=0;i<10;i++){system.out.print(" &q

Java怎样中断一个运行中的线程

程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决, 将导致意外的行为以及细微的.难以发现的错误. 在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 背景中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其 当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来 它可能显得简单,但是,你必须进行一些预警以实现期望的结果.你最好还是牢记以下的几点告诫. 首先,忘掉Th

Java开发中的线程安全选择与Swing

Swing API的设计目标是强大.灵活和易用.特别地,我们希望能让程序员们方便地建立新的Swing组件,不论是从头开始还是通过扩展我们所提供的一些组件. 出于这个目的,我们不要求Swing组件支持多线程访问.相反,我们向组件发送请求并在单一线程中执行请求. 本文讨论线程和Swing组件.目的不仅是为了帮助你以线程安全的方式使用Swing API,而且解释了我们为什么会选择现在这样的线程方案. 本文包括以下内容: ◆单线程规则:Swing线程在同一时刻仅能被一个线程所访问.一般来说,这个线程是事

Java多线程编程中synchronized线程同步的教程_java

0.关于线程同步 (1)为什么需要同步多线程?线程的同步是指让多个运行的线程在一起良好地协作,达到让多线程按要求合理地占用释放资源.我们采用Java中的同步代码块和同步方法达到这样的目的.比如这样的解决多线程无固定序执行的问题: public class TwoThreadTest { public static void main(String[] args) { Thread th1= new MyThread1(); Thread th2= new MyThread2(); th1.sta