[C++ 并发编程] 线程管控

本文详细介绍了C++中线程的基本管控,包括如何发起线程、等待线程完成、传递参数、移交线程归属权,以及如何根据硬件并发能力选择线程数量。特别强调了线程安全和未定义行为的避免策略,如使用std::ref和std::move传递参数,以及通过std::thread::hardware_concurrency()获取系统并发线程数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 线程的基本管控

1.1 发起线程

1.1.1 线程的声明

1.1.2 汇合或分离线程

1.1.3 线程的启动

1.1.4 线程的运行

1.2 等待线程完成(join)

1.3 出现异常情况下等待线程完成

1.4 在后台运行线程

2. 向线程传递参数

2.1 参数传递过程

2.2 使用std::ref传递引用参数

2.3 使用std::move传递参数

2.4 第二个隐藏的参数

2.5 参数传递注意

3.移交线程的归属权

3.1 std::thread的唯一性

3.2  使用std::move移交线程归属权

3.3 小心线程的遗弃

4.在运行时选择线程数量【std::thread::hardware_concurrency()】

5.识别线程

5.1 std::thread::id

5.2 自定义ID

5.3 线程唯一ID

5.3.1 get_id()

5.3.2 std::this_thread::get_id()


1. 线程的基本管控

每个C++程序至少有一个主线程,即运行main()的线程。

1.1 发起线程

class task
{
public:
    void operator()() const
    {
        do_something();
        do_other_something();
    }
};

task f;
std::thread my_thread(f);

1.1.1 线程的声明

任何可调用对象(如函数指针、函数对象、lambda等,即能进行函数调用操作的对象)都适用于std::thread。 所以。在这里我们写了一个task类,重载运算符"()",将其写为能进行函数调用操作的类,生成其对象,初始化线程my_thread。f会被复制到属于新线程的存储空间中,并在那里被调用,由新线程执行。这里要注意一个问题,只要这个C++语句有可能被解释为函数声明,那么编译器就会把它解释为函数声明。如:

std::thread my_thread(func());
[函数返回类型] [函数名][调用参数]

这种被解释为函数申明的就会报错,解决办法:

std::thread my_thread((func()));  //使用func()函数返回的临时对象
std::thread my_thread{func()};    //列表初始化

1.1.2 汇合或分离线程

在线程对象销毁前,必须决定好,是汇合线程(join)还是分离线程(detach),否则在线程对象销毁时,将会在析构时,调用std::terminate()函数终止整个程序。

1.1.3 线程的启动

线程一旦初始化,就开始启动。 我们只需要在线程对象销毁前,决定好,就行了,不用管线程是在join或detach之前结束,还是在detach之后结束。

1.1.4 线程的运行

在线程运行中,注意未定义行为的发生。如:

struct func
{
    int& i;
    func(int *i_):i(i_){}
    void operator()()
    {
        for(int i=0;i<1000000;++i)
            do_something(i);
    }
}

void oops()
{
    int k=0;
    func my_func(k);
    std::thread my_thread(my_func);
    my_thread.detach();
}

func类里,i用的是引用类型,当初始化my_func时,i则初始化为临时变量k的引用,当my_thread线程开始后,结束前,oops函数就已经结束了,临时变量k被销毁,则线程里继续访问k的引用时,将发生未定义行为。避免此问题的发生:1.线程完全自含,所有调用的变量都由线程本身生成,2.汇合线程(join),等待此线程结束再继续执行。

1.2 等待线程完成(join)

汇合线程(join):

join()简单粗暴,会一直等待线程结束。当join()执行完成,线程结束后,会把线程的所有资源释放掉,std::thread关联的对象,将不再有效。所以,join()有且只能调用一次,可使用joinable()进行判断,没有调用过join为true,否则则为false。

if(my_thread.joinable())
{
    my_thread.join();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值