zoukankan      html  css  js  c++  java
  • C++多线程环境下注意共享资源的释放顺序

      比如我现在写一个多线程下载程序,包含DownloadTask、HttpDownload两个类。

    class DownloadTask
    {
         //省略n行代码
    public:
    int m_threads;//需创建的线程总数 CCriticalSection m_cs;
    //临界区
    void Stop(); }; class HttpDownload { //省略n行代码
    HttpDownload(DownloadTask* task): m_task(task) { } public:
    DownloadTask* m_task;
    void Start();//开始下载 }

      每一个HttpDownload对象都是一个线程的执行单元,同一个任务下的所有线程共享同一个DownloadTask对象中的所有资源。如果这样编写下载程序:

    //在某一个函数中
    {
        DownloadTask* myTask =  new DownloadTask()
        HttpDownload* download = new HttpDownload(myTask);
        for(int i = 0; i < myTask->m_threads; ++i)
            AfxBeginThread(downloadThreadFun, download);
        return 0;
    }
    
    UINT downloadThreadFun(LPVOID lParam)
    {
        auto_ptr<HttpDownload> pDownload((HttpDownload*)lParam);
        pDownload->Start();
        return 0;
    }

    void SetStop(DownloadTask* task)
    {
    task->Stop();
    delete task;
    }

      在某一时刻,比如用户点击停止下载时,我们就需要delete掉这个DownloadTask对象。但是如果当前还有线程在运行,这样delete掉就会影响这些线程,直接导致程序出错。

      所以,必须在delete DownloadTask对象前确定此下载任务中所有线程已经停止。于是可以这样写:

    class DownloadTask
    {
         //省略n行代码
    public:
        int m_threads;//需要创建的线程总数
        CCriticalSection m_cs;//临界区
        int m_currentThreads;//当前运行的线程数
        void Stop();
    };
    
    UINT downloadThreadFun(LPVOID lParam)
    {
          auto_ptr<HttpDownload> pDownload((HttpDownload*)lParam);
          CSingleLock singleLock(&pDownload->m_task->m_cs);
          pDownload->Start();
          singleLock.Lock()
          --pDownload->m_task->m_currentThreads;
          return 0;
    }
    
    void SetStop(DownloadTask* task)
    {
         CSingleLock singleLock(&task->m_cs);
         task->Stop();
         singleLock.Lock();
         if(task->m_currentThreads == 0)
            delete task;
         return 0;
    }

      这样就保证在所有线程已经结束时才delete掉这个任务的DownloadTask对象。

  • 相关阅读:
    使用dom4j 解析xml
    xml schema 建立xml文档
    xml dtd 约束建立xml文档
    DBCP 连接池的使用
    c++面向过程和面向对象-C++编译器是如何管理类和对象的
    c++读取文本文件
    一个范围的两个数进行数位的累加,实现对两个数num1和num2的数位和相加
    C++批量注释代码段取消注释代码段快捷键
    利用MATLAB截取一张复杂图片中想要的区域
    python学习之路系列
  • 原文地址:https://www.cnblogs.com/dvwei/p/3427205.html
Copyright © 2011-2022 走看看