当前位置:  编程技术>技术文章 iis7站长之家

c#多线程编程基础实例解析

    来源: 互联网  发布时间:2014-08-30

    本文导语:  本节内容: c#多线程编程 无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为用户提供最好的响应性能,即使应用程序当前正在完成其他工作。要使应用程序能够快速响应用户操...

本节内容:
c#多线程编程

无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为用户提供最好的响应性能,即使应用程序当前正在完成其他工作。要使应用程序能够快速响应用户操作,同时在用户事件之间或者甚至在用户事件期间利用处理器,最强大的方式之一是使用多线程技术。
多线程:线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程。如果某个线程进行一次长延迟操作, 处理器就切换到另一个线程执行。这样,多个线程的并行(并发)执行隐藏了长延迟,提高了处理器资源利用率,从而提高了整体性能。多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。

一、进程与线程
进程,是操作系统进行资源调度和分配的基本单位。是由进程控制块、程序段、数据段三部分组成。一个进程可以包含若干线程(Thread),线程可以帮助应用程序同时做几件事(比 如一个线程向磁盘写入文件,另一个则接收用户的按键操作并及时做出反应,互相不干扰),在程序被运行后中,系统首先要做的就是为该程序进程建立一个默认线程,然后程序可 以根据需要自行添加或删除相关的线程。它是可并发执行的程序。在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位,也是称活动、路径或任务,它有两方面性质:活动性、并发性。进程可以划分为运行、阻塞、就绪三种状态,并随一定条件而相互转化:就绪--运行,运行--阻塞,阻塞--就绪。

线程(thread),线程是CPU调度和执行的最小单位。有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。

主线程,进程创建时,默认创建一个线程,这个线程就是主线程。主线程是产生其他子线程的线程,同时,主线程必须是最后一个结束执行的线程,它完成各种关闭其他子线程的操作。尽管主线程是程序开始时自动创建的,它也可以通过Thead类对象来控制,通过调用CurrentThread方法获得当前线程的引用
多线程的优势:进程有独立的地址空间,同一进程内的线程共享进程的地址空间。启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。

二、多线程优点
1、提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。

2、使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。

3、改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。。
多线程尽管优势明显,但是线程并发冲突、同步以及管理跟踪,可能给系统带来很多不确定性,这些必须引起足够重视。
废话不多说开始我们的多线程之旅。

三、多线程的应用场合:
简单总结了一下,一般有两种情况:
1)多个线程,完成同类任务,提高并发性能
2)一个任务有多个独立的步骤,多个线程并发执行各子任务,提高任务处理效率

四、案例--搬运工
在现实生活中,经常看到这样的场景。有一堆货物,有几个搬运工负责将货物搬运到指定地点。但是搬运工能力不同,有人一次能搬多箱,有人走路比较慢,搬运一趟的时间间隔比较长。搬运工,各自搬运,无先后,互不干扰。我们如何在程序中实现这种场景呢?
案例分析:
最简单的多线程的实际案例。每个人相当于一个线程,并发执行。当货物搬运完毕后,每个线程自动停止。这里暂时不考虑死锁情况。
代码:
 

代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MutiThreadSample.Transport
{
    ///
    /// 搬运工
    ///
    public class Mover
    {
        ///
        /// 总数
        ///
        public static int GoodsTotal { get; set; }
        ///
        /// 间隔时间
        ///
        public static int IntervalTime { get; set; }
        ///
        /// 名称
        ///
        public string Name { get; set; }
        ///
        /// 单位时间搬运量
        ///
        public int LaborAmount { get; set; }
        ///
        /// 搬运
        ///
        public void Move()
        {
            while (GoodsTotal > 0)
            {
                GoodsTotal -= LaborAmount;
                Console.WriteLine("搬运者:{0} 于 {1} 搬运货物 {2}",this.Name,DateTime.Now.Millisecond,this.LaborAmount);
                Thread.Sleep(IntervalTime);
                Console.WriteLine("搬运者:{0} Continue",this.Name);
            }
        }
        ///
        /// 搬运
        ///
        /// 时间间隔
        public void Move(object interval)
        {
            int tempInterval = 0;
            if (!int.TryParse(interval.ToString(), out tempInterval))
            {
                tempInterval = IntervalTime;
            }           
            while (GoodsTotal > 0)
            {
                GoodsTotal -= LaborAmount;
                Console.WriteLine("搬运者:{0} 于 {1} 搬运货物 {2}", this.Name, DateTime.Now.Millisecond, this.LaborAmount);
                Thread.Sleep(tempInterval);
            }
        }
     }
}

测试:
 

代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MutiThreadSample.Transport
{
    ///
    /// 测试搬运
    ///
    public class TestMove
    {
        ///
        /// 搬运
        ///
        public static void Move()
        {
            //测试搬运工
            Mover.GoodsTotal = 200;
            Mover.IntervalTime = 10;
            Mover m1 = new Mover() { Name = "Tom", LaborAmount = 5 };
            Mover m2 = new Mover() { Name = "Jim", LaborAmount = 10 };
            Mover m3 = new Mover() { Name = "Lucy", LaborAmount = 20 };
            List movers = new List();
            movers.Add(m1);
            //movers.Add(m2);
            //movers.Add(m3);
            if (movers != null && movers.Count > 0)
            {
                foreach (Mover m in movers)
                {                   
                    Thread thread = new Thread(new ThreadStart(m.Move));
                    thread.Start();
                }
            }
            //Main Thread continue
            // validate Thread.Sleep()
            //int i =0;
            //int j = 0;
            //while (i < 10)
            //{
            //    while(j 0)
            {
                foreach (Mover m in movers)
                {
                    Thread thread = new Thread(new ParameterizedThreadStart(m.Move));
                    thread.Start(10);
                }
            }
        }
    }
}
 

 通过案例接触了Thread,下面将详细介绍Thread的功能。

五、Thread
 创建并控制线程,设置其优先级并获取其状态。
常用方法:
Start()
导致操作系统将当前实例的状态更改为 ThreadState.Running。
一旦线程处于 ThreadState.Running 状态,操作系统就可以安排其执行。 线程从方法的第一行(由提供给线程构造函数的 ThreadStart 或 ParameterizedThreadStart 委托表示)开始执行。线程一旦终止,它就无法通过再次调用 Start 来重新启动。
Thread.Sleep()
调用 Thread.Sleep 方法会导致当前线程立即阻止,阻止时间的长度等于传递给 Thread.Sleep 的毫秒数,这样,就会将其时间片中剩余的部分让与另一个线程。 一个线程不能针对另一个线程调用 Thread.Sleep。
Interrupt()
中断处于 WaitSleepJoin 线程状态的线程。
Suspend和Resume(已过时)
挂起和继续
在 .NET Framework 2.0 版中,Thread.Suspend 和 Thread.Resume 方法已标记为过时,并将从未来版本中移除。
Abort()
方法用于永久地停止托管线程。一旦线程被中止,它将无法重新启动。
Join()
阻塞调用线程,直到某个线程终止时为止。
ThreadPriority(优先级)
指定 Thread 的调度优先级。
ThreadPriority 定义一组线程优先级的所有可能值。线程优先级指定一个线程相对于另一个线程的相对优先级。
每个线程都有一个分配的优先级。在运行库内创建的线程最初被分配 Normal 优先级,而在运行库外创建的线程在进入运行库时将保留其先前的优先级。可以通过访问线程的 Priority 属性来获取和设置其优先级。
根据线程的优先级调度线程的执行。用于确定线程执行顺序的调度算法随操作系统的不同而不同。操作系统也可以在用户界面的焦点在前台和后台之间移动时动态地调整线程的优先级。
一个线程的优先级不影响该线程的状态;该线程的状态在操作系统可以调度该线程之前必须为 Running。

 1 2 下一页 尾页

    
 
 

您可能感兴趣的文章:

  • c#多线程更新窗口(winform)GUI的数据
  • c# winform 关闭窗体时同时结束线程实现思路
  • c#多线程读取注册表 c#多线程的小例子
  • C#实现终止正在执行的线程
  • c#后台线程访问前台控件并显示信息示例
  • C#线程间不能调用剪切板的解决方法
  • C#实现线程池的简单示例
  • c# 多线程操作progressBar进度条控件的例子
  • C#子线程更新UI控件的方法实例总结
  • C#实现窗体与子线程的交互的方法
  • C#通过接口与线程通信(捕获线程状态)示例代码
  • C#利用子线程刷新主线程分享教程
  • 描述C#多线程中lock关键字的使用分析
  • C#中的多线程多参数传递详解
  • C# 多线程更新进度条progressBar控件的代码一例
  • C# 多线程复制文件并显示进度条的代码
  • c#(asp.net)线程配置总结
  • c#线程同步的问题与实例分析
  • c#多线程中Lock()关键字的用法小结
  • c#钩子本线程内消息拦截的方法
  • c#线程间传递参数详解
  • 高分求c 实现线程池的一个实例
  • 急需关于linux多线程的代码工程实例-高手请进啊
  • JAVA实现多线程的两种方法实例分享
  • haskell实现多线程服务器实例代码
  • python线程池的实现实例
  • Android后台线程和UI线程通讯实例
  • 关于一个线程实例的执行结果问题
  • 线程和进程有什么具体的区别?谁能解释一下,用实例亦可
  • linux c多线程编程实例代码
  • 在Android线程池里运行代码任务实例
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Java中多线程相关类Thread介绍
  • 一个进程创建了两个线程,如何使得当任何一个线程(比如线程a)结束时,同时也结束线程b,也就是使两个线程一起死掉,怎么办呢?
  • Windows和Linux下C++类成员方法作为线程函数方法介绍
  • java 线程,对当前线程(非主线程)调用sleep,为什么主线程(窗口)也没反应了
  • c++的boost库多线程(Thread)编程(线程操作,互斥体mutex,条件变量)详解
  • 如何实现一个线程组内多线程的非同不执行,即一个线程执行完毕后再执行下一个线程???
  • Linux下GCC内置原子操作函数(多线程资源访问)介绍
  • 请问:进程创建的线程是怎样运行的啊,线程的处理函数运行完了,线程就退出了吗?
  • 关于线程的问题,什么样的线程不是active线程?
  • 请问Linux核心支持多线程吗?开发库有线程库吗?线程好用吗?(稳定?)
  • 请问,在一个进程中创建多线程时如何能避免不同的线程获得同一个线程标识
  • 我的一个多线程服务里, 总是有一个线程莫名其妙的变成僵尸线程。
  • 能否通过线程id控制线程的状态?或是观察到线程的状态?
  • 如何在一个线程中启动另外一个线程,然后本线程就退出?
  • 我要设置一个线程的优先级, 这个属性结构并没有线程的id,它怎么知道是设置哪个线程呢?
  • 请问在java多线程中,是只有run(){}内的代码运行在一个新线程下呢?还是这个类中的代码都运行在一个新线程下?
  • gcc链接的库,分不分单线程版本的和多线程版本的?
  • 内核栈~ 内核线程 ~用户线程 之间关系 问题
  • 子线程的数据如何返回给主线程?
  • 如果父线程死掉 那么子线程会不会死掉呢
  • 多线程为何比单线程慢许多?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3