`
ah_fu
  • 浏览: 227866 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

让线程中止的改良办法

阅读更多

    以前常常需要用多线程做一些耗时的工作,同时,为了降低CPU的占用率,在线程中常常会用Thread.Sleep()让线程进入睡眠。
    以前的多线程处理一般是这样的:
public class Work
{
    private bool m_blnIsRunning = false;
    private Thread m_tWork;

    public void Start()
    {
        lock (this)
        {
            if (m_blnIsRunning)
            {
                return;
            }
            m_blnIsRunning = true;
        }
        m_tWork = new Thread(new ThreadStart(_Work_t));
        m_tWork.Start();
    }

    public void Stop()
    {
        lock (this)
        {
            if (!m_blnIsRunning)
            {
                return;
            }
            m_blnIsRunning = false;
        }
        m_tWork.Join();  //如果希望马上退出,则为m_tWork.Abort();
        m_tWork = null;
    }

    private void _Work_t()
    {
        while (m_blnIsRunning)
        {
            //Do something
            Thread.Sleep(1000);
        }
    }
}

    可见这里采用的方法非常野蛮,想中止线程的时候,要吗Stop()方法要等待和线程睡眠一样的时间,要吗强行强行中断。通过采用Event,能够大大改良这样的设计。
    以下是使用AutoResetEvent后的代码:
public class Work
{
    private AutoResetEvent m_oEvent = new AutoResetEvent(false);
    private bool m_blnIsRunning = false;
    private Thread m_tWork;

    public void Start()
    {
        lock (this)
        {
            if (m_blnIsRunning)
            {
                return;
            }
            m_blnIsRunning = true;
        }
        m_oEvent.Reset();
        m_tWork = new Thread(new ThreadStart(_Work_t));
        m_tWork.Start();
    }

    public void Stop()
    {
        lock (this)
        {
            if (!m_blnIsRunning)
            {
                return;
            }
            m_blnIsRunning = false;
        }
        m_oEvent.Set();  //通知事件马上结束
        m_tWork.Join();
        m_tWork = null;
    }

    private void _Work_t()
    {
        while (m_blnIsRunning)
        {
            //Do something
            m_oEvent.WaitOne(1000, false);  //不再使用Thread.Sleep()进行等待了
        }
    }
}

    看来,编程的时候,对《操作系统原理》上的基础理论要认真学习,不能想当然就采用类库中提供的方法。

分享到:
评论

相关推荐

    线程--管理线程(使线程中止,暂停,挂起等)

    接下来,关于线程的中止,需要注意的是,直接使用`Thread.Abort()`方法并不推荐,因为它可能导致不可预测的结果和资源泄露。更好的方式是设置一个终止标志,让线程自己检查并优雅地结束: ```csharp volatile bool ...

    多线程之06三种中止线程的方法比较.docx

    1. **数据不一致性**:当一个线程突然被`stop()`方法中止时,可能会导致其正在更新的数据处于半完成状态,从而引发数据不一致性。 2. **资源未释放**:`stop()`方法会立即释放该线程持有的所有锁和监视器,这可能...

    易语言线程返回数据的方法

    本文将深入探讨易语言中线程返回数据的方法,帮助开发者更好地理解和应用。 一、线程基础知识 线程是操作系统分配处理器时间的基本单元。在易语言中,线程可以用来执行一些耗时但不阻塞主线程的操作,如网络通信、...

    线程处理基本方法

    在本文中,我们将深入探讨线程的基本方法,包括线程的定义、创建、执行、暂停与销毁,以及如何在程序启动时自动开启线程。 线程定义: 线程是进程中的一个执行单元,每个进程至少包含一个线程,而多个线程可以在...

    C++ 如何正确的使用线程 释放线程资源

    在C++中,正确地使用和管理线程是多线程编程中的一个关键话题。线程的创建和释放关系到资源的管理以及程序的稳定性和效率。本文将详细讨论如何在C++中正确使用线程以及如何释放线程资源,并重点阐述joinable状态和...

    c# 多线程任务中结束全部线程

    `语句创建了一个新的线程,并将`threadstart`方法设置为线程的入口点。`t.Start();`则启动了这个线程,使其开始执行`threadstart`方法内的代码。 ### 使用委托进行跨线程调用 由于GUI线程(即主UI线程)不允许从...

    线程外部挂起恢复控制(不使用Suspend与Resume中止线程)

    本人利用Thread.Abort()与Thread.Interrupt()可以引起目标线程异常的特点,开发了一种不使用已过时的方法来变相从外部控制线程的挂起与恢复的技术,原理简单,方便理解。 相关技术参考:...

    3种多线程实现同步方法

    本篇文章将深入探讨三种在C++中实现多线程同步的方法:事件对象、关键代码段和互斥对象。 首先,我们来看**事件对象**。事件对象是一种信号机制,用于线程间通信和同步。在Windows API中,CreateEvent函数创建一个...

    让线程按顺序执行8种方法.doc

    本文将介绍让线程按顺序执行的8种方法,涉及到多线程中许多常用的方法,不止为了知道如何让线程按顺序运行,更是让读者对多线程的使用有更深刻的了解。 一、使用线程的join方法 join()是Thread的方法,作用是调用...

    MFC多线程的创建,包括工作线程和用户界面线程

    通过继承 `CWinThread` 可以创建自己的线程类,并且可以通过调用 `CreateThread` 方法来创建一个新的线程实例。 ##### 3.2 创建线程的方法 创建线程主要通过调用 `CWinThread` 类的 `CreateThread` 方法完成,其...

    如何让程序自动管理线程

    需要注意的是,直接杀死线程可能导致数据不一致或资源泄漏,因此建议提供一种机制让线程自行结束。 4. **线程状态检查**: 使用API函数`GetExitCodeThread`可以检查线程是否已经结束。如果返回值为`STILL_ACTIVE`...

    C# 如何挂起线程、休眠线程和终止线程(源码例)

    休眠线程是一种避免线程过度占用CPU资源的好方法,尤其在需要定时执行或者需要其他线程执行特定任务时。 3. **终止线程**: 终止线程是指强制结束线程的执行,使其不再继续运行。在C#中,直接使用`Thread.Abort()`...

    MFC多线程 工作者线程 用户界面线程

    在Windows编程领域,MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于简化Windows应用程序的开发,包括创建用户界面和实现多线程功能。MFC中的多线程技术使得程序能够同时执行多个任务,提高应用的...

    C++11/14 线程调用类对象和线程传参的方法

    线程调用类对象 在前面的示例中,我们为线程任务使用了通常的函数。实际上,我们可以使用任何可调用对象或者lambda函数,如下调用类对象的例子: #include #include class MyFunctor { public: void operator()...

    C# 跨线程访问UI线程控件

    在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。    下面介绍两种解决方案  第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....

    C#内存释放-线程控制-线程启动-线程暂停

    首先,让我们关注线程控制。在C#中,我们通常使用`System.Threading`命名空间中的类来创建和管理线程。`Thread`类是最基本的线程对象,用于创建和执行新的线程。线程启动通常是通过`Thread.Start()`方法完成的,这...

    Response.Redirect 正在中止线程解决方案

    在ASP.NET开发中,我们经常会遇到“正在中止线程”(ThreadAbortException)的异常,这通常是由于在页面处理过程中使用了`Response.Redirect`或`Response.End`等方法所导致的。这些方法会中断当前线程的执行,引发异常...

    设计滚动字演示线程状态及改变方法

    这个主题“设计滚动字演示线程状态及改变方法”主要涵盖了如何利用Java的多线程特性来实现滚动文字效果,并且管理线程的状态变化。下面我们将详细探讨相关的知识点。 1. **线程基础**: - **线程与进程**:在...

    vc++中的线程锁(线程锁保持线程同步)

    VC++中实现线程锁的方法多种多样,包括临界区(Critical Section)、互斥量(Mutex)、事件对象(Event)等。在提供的文件列表中,如`RWLock.cpp`,可能涉及到了读写锁(Read-Write Lock),这是一种更为复杂的线程...

    线程创建和管理

    线程池适合互不干扰函数以及短作业,因为它不方便控制长作业时,对线程的开始、挂起、和中止等操作。线程池的使用可以减少线程的创建和销毁次数,从而提高程序的性能。 例如,在一个计算阶乘的程序中,我们可以使用...

Global site tag (gtag.js) - Google Analytics