C++11的线程

线程的创建

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

cpp 复制代码
#include <thread>
#include <iostream>
using namespace std;

void func()
{
    cout << "thread run...." << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t(func);

    t.join();

    cout << "main over..." << endl;

    return 0;
}

在上例中,函数func将会运行于线程对象t中,join函数将会阻塞,直到线程函数执行结束,如果线程函数有返回值,返回值将被忽略。

如果不希望线程被阻塞执行,可以调用线程的detach方法,将线程和线程对象分离。比如下面的例子:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
using namespace std;

void func()
{
    cout << "thread run...." << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t(func);

    t.detach();

    ///做其他事情
    cout << "main over..." << endl;

    while(1)
    {
        if(getchar())
        {
            break;
        }
    }

    return 0;
}

通过detach,线程就和线程对象分离了,让线程作为后台线程去执行,当前线程也不会阻塞了。但需要注意的是,detach之后就无法再和线程发生联系了,比如detach之后就不能再通过join来等待 线程执行完成,线程何时执行完成我们也无法控制了。

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

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;

void func(int i, double db, const string& str)
{
    cout << i << endl;
    cout << db << endl;
    cout << str << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t(func, 1, 2, "test");

    t.detach();

    getchar();

    return 0;
}

上面的例子将会输出:

cpp 复制代码
1
2
test

使用这种方法创建线程很方便,但需要注意的是,std::thread出了作用域之后将会析构,这时如果线程函数还没有执行完就会发生错误,因此,需要保证线程函数的生命周期在线程变量std::thread的生命周期之内。

线程不能复制,但可以移动,例如:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;

void func()
{
    cout << "111111111111" << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t(func);
    std::thread t1(std::move(t));

    t1.join();

    getchar();

    return 0;
}

线程被移动之后,线程对象t将不在不代表任何线程了。另外,还可以通过std::bind或lambda表达式来创建线程,代码如下:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
#include <functional>
using namespace std;

void func(int a, double db)
{
    cout << a << "\t" << db << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t1(std::bind(func, 1, 2));
    std::thread t2([](int a, double db){ cout << a << "\t" << db << endl;}, 5, 6);

    t1.join();
    t2.join();

    getchar();

    return 0;
}

需要注意的是线程对象的生命周期,比如下面的代码:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
#include <functional>
using namespace std;

void func(int a, double db)
{
    cout << a << "\t" << db << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t1(func, 1, 2);

    ///join函数注释了,会有异常发生
    ///t1.join();

    return 0;
}

上面的代码运行可能会抛出异常,因为线程对象可能先于线程函数结束,应该保证线程对象的生命周期在线程函数执完时仍然存在。可以通过join方法来阻塞等待线程函数执行完,或者通过detach方法让线程在后台执行。

线程的基本用法

获取当前信息

线程可以通过当前线程的ID,还可以获取CPU核心数量,例如:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
#include <functional>
using namespace std;

void func()
{
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t1(func);

    cout << t1.get_id() << endl;

    cout << std::thread::hardware_concurrency() << endl;

    t1.join();

    return 0;
}

线程休眠

可以使当前线程休眠一定时间,代码如下:

cpp 复制代码
#include <thread>
#include <iostream>
#include <string.h>
#include <string>
#include <functional>
using namespace std;

void func()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    cout << "time out" << endl;
}

/// g++ thread.cpp  -lpthread
int main()
{
    std::thread t1(func);

    t1.join();

    return 0;
}

在上面的例子中,线程将会休眠3秒,3秒之后将打印time out。

相关推荐
2501_933329555 小时前
媒介宣发技术实践:Infoseek舆情系统的AI中台架构与应用解析
开发语言·人工智能·架构·数据库开发
[J] 一坚6 小时前
嵌入式高手C
c语言·开发语言·stm32·单片机·mcu·51单片机·iot
odoo中国6 小时前
Odoo 19技术教程 : 如何在 Odoo 19 中创建 Many2one 组件
开发语言·odoo·odoo19·odoo技术·many2one
借雨醉东风6 小时前
程序分享--常见算法/编程面试题:旋转矩阵
c++·线性代数·算法·面试·职场和发展·矩阵
逻辑驱动的ken6 小时前
Java高频面试考点场景题14
java·开发语言·深度学习·面试·职场和发展·求职招聘·春招
云泽8088 小时前
笔试算法 - 双指针篇(二):四大经典求和题型 + 有效三角形计数问题
c++·算法
techdashen8 小时前
Cloudflare 如何把一个大型代理拆成三个小服务来提升可靠性
开发语言·rust
geovindu8 小时前
go: Chain of Responsibility Pattern
开发语言·设计模式·golang·责任链模式
十五年专注C++开发8 小时前
WaitingSpinnerWidget: 一个高度可配置的自定义Qt等待加载动画组件
开发语言·c++·qt·waitingspinner
qeen879 小时前
【数据结构】树的基本概念及存储
c语言·数据结构·c++·学习·