• c++11并发之std::thread


    知识链接:

    https://www.cnblogs.com/lidabo/p/7852033.html

    构造函数如下:

    default (1)
        thread() noexcept;
    initialization(2)
        template <class Fn, class... Args> explicit thread (Fn&& fn, Args&&... args);
    copy [deleted] (3)
        thread (const thread&) = delete;
    move [4]
        thread (thread&& x) noexcept;
    (1).默认构造函数,创建一个空的 thread 执行对象。
    
    
    (2).初始化构造函数,创建一个 thread 对象,该 thread 对象可被 joinable,新产生的线程会调用 fn 函数,该函数的参数由 args 给出。
    
    (3).拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
    
    (4).move 构造函数,move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
    
    注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached
    #include<thread>  
    #include<chrono> 
    #include <iostream>
    using namespace std;  
    void fun1(int n)  //初始化构造函数  
    {  
       cout << "Thread " << n << " executing
    ";  
       n += 10;  
       this_thread::sleep_for(chrono::milliseconds(10));  
    }  
    void fun2(int & n) //拷贝构造函数  
    {  
        cout << "Thread " << n << " executing
    ";  
        n += 20;  
        this_thread::sleep_for(chrono::milliseconds(10));  
    }  
    int main()  
    {  
        int n = 0;  
        thread t1;               //t1不是一个thread  
        thread t2(fun1, n + 1);  //按照值传递  
        t2.join();  
        cout << "n=" << n << '
    ';  
        n = 10;  
        thread t3(fun2, ref(n)); //引用  
        thread t4(move(t3));     //t4执行t3,t3不是thread  
        t4.join();  
        cout << "n=" << n << '
    ';  
        system("pause");
        return 0;  
    } 
    View Code
    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    void running()
    {
        cout << "thread is running..." << endl;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        // 栈上
        thread t1(running); // 根据函数初始化执行
        thread t2(running);
        thread t3(running);
    
        // 线程数组
        thread th[3] {thread(running), thread(running), thread(running)}; // 执行
    
        // 堆上
        thread* pt1(new thread(running));
        thread* pt2(new thread(running));
        thread* pt3(new thread(running));
    
        // 线程指针数组
        thread* pth(new thread[3]{thread(running), thread(running), thread(running)});
    
        return a.exec();
    }

    多线程传递参数

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    void running(const char* str,const int id)
    {
        cout << "thread" << id << "is running..."<< str << endl;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        // 栈上
        thread t1(running,"hello1",1); // 根据函数初始化执行
        thread t2(running,"hello2",2);
        thread t3(running,"hello3",3);
    
    
        return a.exec();
    }

    join

    join 是让当前主线程等待所有的子线程执行完,才能退出。

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    void running(const char* str,const int id)
    {
        cout << "thread" << id << "is running..."<< str << endl;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        // 栈上
        thread t1(running,"hello1",1); // 根据函数初始化执行
        thread t2(running,"hello2",2);
        thread t3(running,"hello3",3);
    
        cout << t1.joinable() << endl;
        cout << t2.joinable() << endl;
        cout << t3.joinable() << endl;
    
        t1.join(); // 主线程等待当前线程执行完成再退出
        t2.join();
        t3.join();
    
    
        return a.exec();
    }
    View Code

    detach

    线程 detach 脱离主线程的绑定,主线程挂了,子线程不报错,子线程执行完自动退出。
    线程 detach以后,子线程会成为孤儿线程,线程之间将无法通信。
    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    void running(const char* str,const int id)
    {
        cout << "thread" << id << "is running..."<< str << endl;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        // 栈上
        thread t1(running,"hello1",1); // 根据函数初始化执行
        thread t2(running,"hello2",2);
        thread t3(running,"hello3",3);
    
        cout << t1.joinable() << endl;
        cout << t2.joinable() << endl;
        cout << t3.joinable() << endl;
    
        t1.detach();
        t2.detach();
        t3.detach();
    
    
        return a.exec();
    }
    View Code

    获取cpu核心个数

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        auto n = thread::hardware_concurrency();//获取cpu核心个数
        cout << n << endl; # 4
    
        return a.exec();
    }

    CPP原子变量与线程安全。

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    using namespace std;
    
    const int N = 1000000;
    int num = 0;
    
    void run()
    {
        for (int i = 0; i < N; ++i){
            num++;
        }
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        clock_t start = clock();
    
        thread t1(run);
        thread t2(run);
        t1.join();
        t2.join();
    
        clock_t end = clock();
        cout << "num=" << num << ",spend time:" << end - start << "ms" << endl;
    
        return a.exec();
    }

    运行结果:num=1157261,spend time:9ms
    结果并不是200000,这是由于线程之间的冲突

    互斥量

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    #include <mutex>
    using namespace std;
    
    const int N = 1000000;
    int num = 0;
    mutex m;
    void run()
    {
        m.lock();
        for (int i = 0; i < N; ++i){
            num++;
        }
        m.unlock();
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        clock_t start = clock();
    
        thread t1(run);
        thread t2(run);
        t1.join();
        t2.join();
    
        clock_t end = clock();
        cout << "num=" << num << ",spend time:" << end - start << "ms" << endl;
    
        return a.exec();
    }
    View Code

    运行结果:num=2000000,spend time:5ms

    原子变量。

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    #include <mutex>
    using namespace std;
    
    const int N = 1000000;
    atomic_int num {0}; // 不会发生线程冲突,线程安全
    
    void run()
    {
        for (int i = 0; i < N; ++i){
            num++;
        }
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        clock_t start = clock();
    
        thread t1(run);
        thread t2(run);
        t1.join();
        t2.join();
    
        clock_t end = clock();
        cout << "num=" << num << ",spend time:" << end - start << "ms" << endl;
    
        return a.exec();
    }

    C++11 并发之std::atomic。

    lambda与多线程

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    #include <mutex>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        auto fun = [](const char* str){cout << str << endl;};
        thread t1(fun,"hello world");
        thread t2(fun,"hello C++");
    
        return a.exec();
    }


    时间等待相关

    #include <QCoreApplication>
    #include<thread>
    #include<chrono>
    #include <iostream>
    #include <mutex>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        auto fun = [](const char* str){
            this_thread::sleep_for(chrono::seconds(1));
            this_thread::yield();// 让cpu执行其他空闲线程
            cout << this_thread::get_id() << endl;
            cout << str << endl;
        };
        thread t1(fun,"hello world");
    
        return a.exec();
    }
    View Code
  • 相关阅读:
    分时段查询数据
    优秀产品经理的7大核心技能
    控制台打印螺旋数组
    强大的jquery,再次让我为之鼓掌——三维展示插件
    立象条码打印机PPLB类单双标签打印
    一次与德国程序员的交流
    用ASP为Discuz扩展点小功能
    GDI+ 小破孩动画
    回应YeanJay同学jQuery按钮改变DIV背景色
    C# Dock Style 设置
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10457953.html
Copyright © 2020-2023  润新知