菜鸟笔记
提升您的技术认知

c++11并发之std::thread

构造函数如下:

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";  
   n += 10;  
   this_thread::sleep_for(chrono::milliseconds(10));  
}  
void fun2(int & n) //拷贝构造函数  
{  
    cout << "Thread " << n << " executing\n";  
    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';  
    n = 10;  
    thread t3(fun2, ref(n)); //引用  
    thread t4(move(t3));     //t4执行t3,t3不是thread  
    t4.join();  
    cout << "n=" << 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();
}