2021-11-02

本文总结了C++中线程编程的关键知识点,包括线程创建方法、线程间数据传递、线程控制函数、程序退出相关函数及条件变量的应用。通过具体代码示例详细解释了如何使用std::thread、std::promise、std::future等API。

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

                   **

C++ std::thread重要知识点总结**

1.创建线程方法
(1)C++11中使用thread创建线程,创建线程必须传入一个可执行体作为参数,启动线程建议使用join。
(2)C++11很提供了packaged_task类型,不用直接使用std::thread和std::promise,直接就能够生成线程,但需要自己启动任务。
#include
#include
using namespace std;
int f() {
string hi = “hello, world!”;
cout << hi << endl;
return hi.size();
}
int main() {
packaged_task<int ()> task(f);
auto result = task.get_future();
task();
cout << result.get() << endl;
return 0;
}

输出为:
hello,world
13
2.在不同线程之间传递数据
C++中使用std::promise和std::future两种数据结构来实现数据在不同线程之间传递。其中promise为范型的数据结构,既线程之间传递的数据类型由promise定义,如promise:promise,则线程之间传递的数据是整形。
promise的get_future()方法返回的是一个future数据结构。
std::future提供一个访问异步操作结果的途径。
使用场景如:主线程中获取子线程的数据
(1)主线程中定义一个promise,命名为p;
(2)主线程调用p.get_future(),并把返回值保存为引用f
(3)主线程启动一个子线程,并把p作为启动参数传给子线程
(4)主线程调用f.get(),但是此时子线程还未将数据放入promise内,所以主线程挂起
(5)子线程执行完,获取到结果,并把结果写入p
(6)主线程从f.get()的调用中被唤醒,获取到子线程写入p的值,继续执行
3.线程的一些控制函数
(1)std::this_thread表示当前线程
(2)get_id(),获取线程唯一ID
(3)sleep_for(),使线程成睡一定时间
在这里插入图片描述
4.程序退出相关函数
(1)abort():异常中止程序,不承诺清理资源
(2)exit(),正常退出整个程序(包括所有线程)对于C++程序而言,会调用静态对象的析构函数,并处理好IO缓冲。如果想使用exit()来从多线程函数中退出,必须等所有的线程都执行完。如果不进行这个同步的话,exit()执行的时候会对析构静态对象,而哪些在调用exit()之后才运行结束的线程也会析构静态对象,会导致对静态对象的二次析构,从而导致未定义的结果
5.条件变量std::condition_variable作用
条件变量 std::condition_variable 是为了解决死锁而生,当互斥操作不够用而引入的。比如,线程可能需要等待某个条件为真才能继续执行, 而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。condition_variable 实例被创建出现主要就是用于唤醒等待线程从而避免死锁,td::condition_variable的 notify_one() 用于唤醒一个线程;notify_all() 则是通知所有线程。下面是一个生产者和消费者模型的例子:

描述 用户行为日志表tb_user_log id uid artical_id in_time out_time sign_in 1 101 9001 2021-11-01 10:00:00 2021-11-01 10:00:31 0 2 102 9001 2021-11-01 10:00:00 2021-11-01 10:00:24 0 3 102 9002 2021-11-01 11:00:00 2021-11-01 11:00:11 0 4 101 9001 2021-11-02 10:00:00 2021-11-02 10:00:50 0 5 102 9002 2021-11-02 11:00:01 2021-11-02 11:00:24 0 (uid-用户ID, artical_id-文章ID, in_time-进入时间, out_time-离开时间, sign_in-是否签到) 场景逻辑说明:artical_id-文章ID代表用户浏览的文章的ID,artical_id-文章ID为0表示用户在非文章内容页(比如App内的列表页、活动页等)。 问题:统计202111月每天的人均浏览文章时长(秒数),结果保留1位小数,并按时长由短到长排序。 输出示例: 示例数据的输出结果如下 dt avg_viiew_len_sec 2021-11-01 33.0 2021-11-02 36.5 解释: 11月1日有2个人浏览文章,总共浏览时长为31+24+11=66秒,人均浏览33秒; 11月2日有2个人浏览文章,总共时长为50+23=73秒,人均时长为36.5秒。以下写法:select dt, round(avg(diff),1) avg_viiew_len_sec from ( select uid, date(in_time) dt sum(timestampdiff(SECOND,in_time,out_time)) diff from tb_user_log where dt='2021-11' group by uid,dt )t group by dt order by avg_viiew_len_sec 报错程序异常退出, 请检查代码"是否有数组越界等异常"或者"是否有语法错误" SQL_ERROR_INFO: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sum(timestampdiff(SECOND,in_time,out_time)) diff\nfrom\n tb_user_log\nwhere dt='' at line 9"
03-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值