多线程

在最近的一个项目中,比较多的接触到了异步委托的调用。对其内部原理很模糊,于是乎就认真研究了一番,幸有点小悟。


什么是多线程?

当一个程序开始运行时,它就是一个进程,进程所指包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。浏览器就是一个很好的多线程的例子,在浏览器中你可以在下载JAVA小应用程序或图象的同时滚动页面,在访问新页面时,播放动画和声音,打印文件等。

比喻加深认识

假设有一个公司,公司里有很多各司其职的职员,那么我们可以认为这个正常运作的公司就是一个进程,而公司里的职员就是线程。一个公司至少得有一个职员吧,同理,一个进程至少包含一个线程。在公司里,你可以一个职员干所有的事,但是效率很显然是高不起来的,一个人的公司也不可能做大;一个程序中也可以只用一个线程去做事,事实上,一些过时的语言如fortune,basic都是如此,但是象一个人的公司一样,效率很低,如果做大程序,效率更低——事实上现在几乎没有单线程的商业软件。公司的职员越多,老板就得发越多的薪水给他们,还得耗费大量精力去管理他们,协调他们之间的矛盾和利益;程序也是如此,线程越多耗费的资源也越多,需要CPU时间去跟踪线程,还得解决诸如死锁,同步等问题。总之,如果你不想你的公司被称为“皮包公司”,你就得多几个员工;如果你不想让你的程序显得稚气,就在你的程序里引入多线程吧! 


在c#中是怎么使用的?

其实,在c# 中,线程的使用还是挺简单。它的操作都包含在System.Threading名字空间中,所以,首先需要导入这个名字空间。


怎么创建一个线程?

Thread th =new Thread(new ThreadStart(方法名));

也可以在构造方法里写一个匿名委托实例化如:

Thread th = new Thread(delegate() {处理逻辑代码});


关于线程的启动,可以有参数和无参数的,csdn博客中,周公讲的不错,链接如下

http://blog.csdn.net/zhoufoxcn/article/details/4402999


同时它还有几个常用的方法

             Start():启动线程    
             Sleep(int):静态方法,暂停当前线程指定的毫秒数
             Abort():通常使用该方法来终止一个线程,这个方法终止后,不能重新再start,否则异常。
            Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复
             Resume():恢复被Suspend()方法挂起的线程的执行  
            Join()等待当前线程,知道它执行完成。
线程的几个常见状态
     Aborted:线程已停止 
  AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止 
  Background:线程在后台执行,与属性Thread.IsBackground有关 
  Running:线程正在正常运行 
  Stopped:线程已经被停止 
  StopRequested:线程正在被要求停止 
  Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行) 
  SuspendRequested:线程正在要求被挂起,但是未来得及响应 
  Unstarted:未调用Thread.Start()开始线程的运行 
  WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态 

 

线程的优先级设置

当线程之间争夺CPU时间时,CPU按照是线程的优Highest,AboveNormal,Normal,BelowNormal,Lowest先级给予服务的。在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。给一个线程指定优先级


同步和异步。

我一直都很模糊着两个的概念。也不是很清楚这同步异步与线程之间的关系。。。

原来,同步和异步,跟线程没有直接的关系。这两个概念似乎源于操作系统通信里面。


同步

由于程序中的代码区在线程中是可以共用的,所以,当多个线程访问同一个块代码时可能出现错误和异常,故此有了同步解决方案。在c#中,有两个关键字可用,一个Lock,一个是Monitor,其实内质上,Lock也是在调用Monitor的东西。用Monitor的Enter方法锁定一个对象,Exit释放一个对象。当用这个Monitor来锁定对象后,其他线程只有等待,待执行完成后,CPU根据排队线程的先后顺序执行。


而异步又是怎么回事?

有个比喻,说是,你妈叫你回家吃饭,你可以回也可以不回。你妈照样吃饭。

在网站中,一个视频还在加载中,用户也可以操作其他的东西。。

在WinForm中,若有某个处理过程需要花费很久的时间,而又不至于让前端UI无法卡死等待,可采用多线程异步模式。

 http://www.dzsc.com/data/html/2009-11-5/79938.html

using System;
using System.Threading;
namespace AsyncDelegateDemo
{
    delegate void AsyncFoo(int i);

    class Program
    {
        /// ﹤summary﹥///
        /// /// 输出当前线程的信息  ///
        /// ﹤/summary﹥     ///
        /// ﹤param nAME="name"﹥方法名称﹤/param﹥
        static void PrintCurrThreadInfo(string name)
        {
            Console.WriteLine("Thread Id of " + name + " is: " + Thread.CurrentThread.ManagedThreadId + ", current thread is " + (Thread.CurrentThread.IsThreadPoolThread ? "" : "not ") + "thread pool thread.");
        }


        /// 测试方法,Sleep一定时间

        /// ﹤/summary﹥

        /// ﹤param name="i"﹥Sleep的时间﹤/param﹥

        static void Foo(int i)
        {

            PrintCurrThreadInfo("Foo()");

            Thread.Sleep(i);

        }

        /// ﹤summary﹥

        /// 投递一个异步调用

        /// ﹤/summary﹥

        static void PostAsync()
        {

            AsyncFoo caller = new AsyncFoo(Foo);

            caller.BeginInvoke(1000,

            new AsyncCallback(FooCallBack), caller);

        }

        static void Main(string[] args)
        {

            PrintCurrThreadInfo("Main()");

            for (int i = 0; i < 10; i++)
            {

                PostAsync();

            }

            Console.ReadLine();

        }

        static void FooCallBack(IAsyncResult ar)
        {

            PrintCurrThreadInfo("FooCallBack()");

            AsyncFoo caller = (AsyncFoo)ar.AsyncState;

            caller.EndInvoke(ar);

        }

    }

}

           初步研究了异步委托后,发现异步委托是在线程池中新开一个线程.那么异步委托和多线程又有什么区别呢?为什么又要加个异步委托呢,用多线程就行了.在Google搜索到以下文字.
         1.异步请求一般用在IO等耗时操作上,他的好处是函数调用立即返回,相应的工作线程立即返还给系统以供重用。由于系统的线程资源是非常宝贵的,通常有一定的数目限制,如.net默认是25。若使用异步方式,用这些固定数目的线程在固定的时间内就可以服务更多的请求,而如果用同步方式,那么每个请求都自始至终占用这一个线程,服务器可以同时服务的请求数就少了。当异步操作执行完成后,系统会从可用线程中选取一个执行回调程序,这时的这个线程可能是刚开始发出请求的那个线程,也可能是其他的线程,因为系统选取线程是随机的事情,所以不能说绝对不是刚开始的那个线程。多线程是用来并发的执行多个任务。
(注:摘自http://www.itwenku.com/net/5/21930.htm),请达人们给菜鸟解惑.谢谢
.         2.NET系统提供的多线程机制ThreadPool就是帮助你简化这些线程控制细节的,而几乎所有的.NET异步编程都是通过ThreadPool实现的。(摘自知秋一叶)
          3.线程池的实现方法与线程是不一样的.初始化时在线程池里的线程为0.当进程需要一个线程时,创建一个线程,由此线程执行用户的方法.需要注意的是,此线程执行完后并不立即销毁,而是挂起等待,如果有其他方法需要执行,回唤醒进行处理.只有当它等到40秒(没有官方记录,有可能是其它数字)还没有任务执行时才唤醒自己,并销毁自己,释放资源.当然,如果线程池中的线程不够处理任务时,会再次创建一个新线程进行执行.详细的介绍请看

4.同步 例子

http://www.cnblogs.com/michaelxu/archive/2008/09/20/1293716.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值