zoukankan      html  css  js  c++  java
  • 使用C++11的thread取代QThread

      因为在做的工程项目里使用了Qt,而实际上不涉及到屏幕显示,工程代码里使用了QThread,且没有使用Qt核心的信号与槽,为了以后移植准备使用更加通用的C++11 stl中的thread取代QThread。

      下面是一些测试过程,因为没有为这个小测试建一个版本控制,所以为了能记录每步测试修改,这里将编写代码编写博客,开始吧。

     1 #include <iostream>
     2 #include <thread>
     3 #include <chrono>
     4 #include <functional>
     5 
     6 using namespace std;
     7 
     8 class MyThread
     9 {
    10 public:
    11     MyThread()
    12     {
    13         thread t([this]()-> void {
    14             
    15             run();
    16 
    17         });
    18         t.detach();
    19     }
    20 
    21 public:
    22     void run()
    23     {
    24         for(int i=0;i<5;i++)
    25         {
    26                     cout<<"Hello Nelson!"<<endl;
    27             std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    28         }
    29     }
    30 };
    31 
    32 int main(int argc,char *argv[])
    33 {
    34 
    35     MyThread mythread;
    36 
    37     cout<<"main thread is over"<<endl;
    38 
    39     return 0;
    40 }
    View Code

      上面代码运行环境,Ubuntu 16.04.4  g++版本:gcc version 5.4.0

      先使用VS2008编译不行,VS2010编译不行,主要报错是说没有std::thread,这里有个文档,里面有VS各个版本对C++11支持说明,https://blogs.msdn.microsoft.com/vcblog/2011/09/12/c11-features-in-visual-c-11/  (C++11 Features in Visual C++11)。

      上述代码的编译指令是这样的:g++ -std=c++11 -pthread test.cpp -o test        

      注意指定标准C++11和-pthread线程库链接选项,test.c代码里没有#include <pthread> ,如果去掉-phtread编译,结果提示undefined reference to `pthread_create'。运行test,结果如下:

      

      子线程建立后,主线程和子线程的线程调度是不确定的,索引多执行几次test后,结果会不一样。因为thread对象调用了detach,所以子线程运行状态与线程对象完全无关,thread t在构造函数执行完了之后就消亡了。如果验证子线程在主线程结束了以后还在运行呢?在子线程里向文件里写内容。

    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <functional>
    #include <fstream>
    
    using namespace std;
    
    class MyThread
    {
    public:
        MyThread()
        {
            thread t([this]()-> void {
                
                run();
    
            });
            t.detach();
        }
    
    public:
        void run()
        {
            fstream f;
            f.open("test.txt",ios::out|ios::trunc);
    
            for(int i=0;i<5;i++)
            {
                        cout<<"Hello Nelson!"<<endl;
                f<<"Write One Line
    ";
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                f<<"Write The Other Line
    ";
            }
            f.close();
        }
    };
    
    int main(int argc,char *argv[])
    {
    
        MyThread mythread;
    
        cout<<"main thread is over"<<endl;
    
        std::this_thread::sleep_for(std::chrono::milliseconds(10));  //delay for file create
    
        return 0;
    }
    View Code

      编译运行,结果如下:

      

      和想象中的结果不一致,预期是子线程独立运行,在文档中写入多行文字,而且结果中居然一行也没有显示。修改主线程休眠时间,由10ms改为10s,结果如下:

      

      这就说明文件读写是很正常的。

      主线程关闭时也关闭了子线程?不然无法理解Hello Nelson不接着打印,同时文件写操作内容不见了。文件写操作内容不见了则可以说明这种情况下,子线程内部的操作都是不安全的,不可预期的。

      下面测试让主线程主动关闭子线程(通过控制变量bRun做到的),这才是需要的线程基本控制。

     1 #include <iostream>
     2 #include <thread>
     3 #include <chrono>
     4 #include <functional>
     5 #include <fstream>
     6 
     7 using namespace std;
     8 
     9 class MyThread
    10 {    
    11 private:
    12     bool bRun;
    13 
    14 public:
    15     void DisableThreadRun()
    16     {
    17         bRun = false;
    18     }
    19 
    20 public:
    21     MyThread()
    22     {
    23         bRun = true;
    24 
    25         thread t([this]()-> void {
    26             
    27             run();
    28 
    29         });
    30         t.detach();
    31     }
    32 
    33 public:
    34     void run()
    35     {
    36         fstream f;
    37         f.open("test.txt",ios::out|ios::trunc);
    38 
    39         while(bRun)
    40         {    
    41             for(int i=0;i<5;i++)
    42             {
    43                         cout<<"Hello Nelson!"<<endl;
    44                 f<<"Write One Line
    ";
    45                 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    46                 f<<"Write The Other Line
    ";
    47             }
    48             f.flush();
    49         }
    50         f.close();
    51         cout<<"sub thread is running out"<<endl;
    52     }
    53 };
    54 
    55 int main(int argc,char *argv[])
    56 {
    57     MyThread mythread;
    58 
    59     std::this_thread::sleep_for(std::chrono::milliseconds(10000));  //delay for file create
    60     mythread.DisableThreadRun();
    61     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
    62 
    63     cout<<"main thread is over"<<endl;
    64 
    65     return 0;
    66 }
    View Code

      测试结果如下

      

      主要是子线程函数,这里使用lambda表达式用起来就是非常的爽,【capture】属性中填入this(参见上一篇博客),lambda表达式中就可以获得所在类里的所有权限了,直接调用类成员方法run。开起来是不是跟QThread里的Run一样。

        使用C++11的thread去掉QThread很容易了吧。

  • 相关阅读:
    对"对DllRegisterServer的调用失败,错误代码为0x8007005"的解决办法
    Struts FileUpload 异常处理之Processing of multipart/formdata request failed.
    Java设计模式之简单工厂模式(转载)
    [转]VS 2008 中文"试用版"变"正式版"方法
    XP系统中多用户,自动登陆(一)
    常见Flash无法播放现象处理
    [转]顺利迈出职业成功的第一步
    VS2005的BUG:Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'
    OO设计原则
    ASPX页面生成HTML的方法
  • 原文地址:https://www.cnblogs.com/kanite/p/8417642.html
Copyright © 2011-2022 走看看