天天看点

C++11:线程线程的创建回收线程资源获取线程ID和CPU核心数

在C++11之前,C/C++一直是一种顺序的编程语言。顺序是指所有指令都是串行执行的,即在相同的时刻,有且仅有单个CPU的程序计数器执行代码的代码段,并运行代码段中的指令。而C/C++代码也总是对应地拥有一份操作系统赋予进程的包括堆、栈、可执行的(代码)及不可执行的(数据)在内的各种内存区域。

而在C++11中,一个相当大的变化就是引入了多线程的支持。这使得C/C++语言在进行线程编程时,不比依赖第三方库。

线程的创建

用std::thread创建线程非常简单,只需要提供线程函数或函数对象即可,并且可以同时指定线程函数的参数。

#include <thread>
#include <iostream>
using namespace std;

void func1()
{
    while()
    {
        cout << __func__ << endl;
    }
}

void func2()
{
    while()
    {
        cout << __func__  << endl;
    }
}


int main()
{
    thread t1(func1);   //子线程1
    thread t2(func2);   //子线程2

    while()//主线程
    {
        cout << __func__ << endl;
    }

    return ;
}
           

线程还可以接收任意个数的参数:

#include <thread>
#include <iostream>
using namespace std;

void func(int a, char ch, const char *str)
{
    std::cout << "a = " << a << "\n";
    std::cout << "ch = " << ch << "\n";
    std::cout << "str = " << str << "\n";
}

int main()
{
    std::thread t(func, , 'a', "mike");   //子线程, 需要头文件#include <thread>

    while(); //特地写一个死循环,让程序不结束

    return ;
}
           

运行结果如下:

C++11:线程线程的创建回收线程资源获取线程ID和CPU核心数

回收线程资源

std::thread::join等待线程结束(此函数会阻塞),并回收线程资源,如果线程函数有返回值,返回值将被忽略。

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void pause_thread(int n)
{
    //指定当前线程休眠一定的时间
    this_thread::sleep_for(chrono::seconds(n));
    cout << "pause of " << n << " seconds ended\n";
}

int main()
{
    cout << "Spawning 3 threads...\n";
    thread t1(pause_thread, );
    thread t2(pause_thread, );
    thread t3(pause_thread, );

    cout << "Done spawning threads. Now waiting for them to join:\n";

    t1.join();//等待线程结束(此函数会阻塞)
    t2.join();
    t3.join();
    cout << "All threads joined!\n";

    return ;
}
           

运行结果如下:

C++11:线程线程的创建回收线程资源获取线程ID和CPU核心数

如果不希望线程被阻塞执行,可以调用线程的std::thread::detach,将线程和线程对象分离,让线程作为后台线程去执行。但需要注意的是,detach之后就无法在和线程发生联系了,比如detach之后就不能再通过join来等待执行完,线程何时执行完我们也无法控制。

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void pause_thread(int n)
{
    this_thread::sleep_for (chrono::seconds(n));
    cout << "pause of " << n << " seconds ended\n";
}

int main()
{
    cout << "Spawning and detaching 3 threads...\n";
    thread(pause_thread,).detach();
    thread(pause_thread,).detach();
    thread(pause_thread,).detach();
    cout << "Done spawning threads.\n";

    cout << "(the main thread will now pause for 5 seconds)\n";

    // give the detached threads time to finish (but not guaranteed!):
    pause_thread();

    return ;
}
           

运行结果如下:

C++11:线程线程的创建回收线程资源获取线程ID和CPU核心数

获取线程ID和CPU核心数

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void func()
{
    this_thread::sleep_for (chrono::seconds());//休眠1秒
    //获取当前线程id
    cout << "func id = " << this_thread::get_id() << endl;
}

int main()
{
    thread t(func);
    cout << "t.get_id() = " << t.get_id() << endl; //获取线程t的id
    cout << "main id = "<<this_thread::get_id() << endl; //主线程id
    cout << "cup num = " << thread::hardware_concurrency() << endl;//获取cpu核心数,失败返回0

    t.join(); //线程阻塞

    return ;
}
           

运行结果如下:

C++11:线程线程的创建回收线程资源获取线程ID和CPU核心数

参考资料:深入应用C++11 代码优化与工程级应用

继续阅读