本课程,讲解的重点定位在c++11新标准中的多线程开发部分,同时,老师还会结合自己的经验把多线程的讲解进一步拓展到一个比较大的范畴,因为无论是c++11多线程开发还是各种其他的多线程开发实现方法,都有很多类似的地方或者说是相通的理论、技巧和要遵循的规则;同学们再学完以后,将对多线程程序开发有一个全面任何和深刻理解,从此再也不用担心自己写不好多线程程序了。
你将收获
适用人群
课程介绍
课程目录
正在加载中...
同学笔记
2020-09-20 18:51:53
总结线程:
1、线程是用来执行代码的;
2、把线程这个东西理解为代码的执行道路,一个新线程代表一个新道路;
3、一个进程自动包含一个主线程,主线程随着进程默默地启动并运行,我们可以通过编码来创建其他线程(非主线程);
注意:不建议创建超过200-300个线程,因为上下文切换占用了本该程序运行的时间,线程多不代表效率高,根据项目来确定创建多少个线程。
4、一个进程至少含有一个线程(主线程)。进程和线程唇齿相依,爹和儿子的关系。
5、多线程程序就是可以同时干多个事情(并发),所以运行效率高。但是到底有多高,并不是一个很容易评估和量化的东西。
6、一个可执行程序运行,就是一个进程。
二、实现并发的手段
1、多进程并发
Word启动后就是进程,IE浏览器启动后也是进程。
账号服务器,游戏逻辑服务器。服务器进程之间的通信。
进程之间的通信(同一台电脑:管道、文件消息队列、共享内存;
不同电脑:socket通讯技术)
2、多线程并发:单个进程中创建多个线程。
线程:轻量级的进程,每个线程都有自己独立的运行路径,但是同一个进程中的所有线程共享地址空间(共享内存)全局变量,指针,引用都可以子在线程之间传递,所以:使用多线程开销远远小于多进程。
共享内存带来的新问题就是,数据的一致性:A线程 B线程
多进程并发和多线程并发虽然可以混合使用,但是有限考虑多线程并发。
和进程相比,线程的优点:
a)线程的启动速度更快,更轻量级;
b) 系统资源开销更少,执行速度更快,比如共享内存这种通信方式比任何其他的通信方式都快;
缺点:
使用有一定的难度,要小心处理数据一致性问题;
三、C++11新标准线程库
以往创建线程:
Windows:CreateThread(),_beginthred(), _beginthredexe()
linux: pthread_create():创建线程
临界区、互斥量
以往多线程代码不能跨平台使用;
POSIX thread(pthread):这个库跨平台;需要做一番配置才能使用,用起来不是很方便。
从C++11新标准,C++语言本身增加多线程的支持,这就意味着可移植性了(跨平台);
2020-03-05 10:48:03
来源:async、future、packaged_task、promise 查看详情
1. std::async、std::futrue创建后台任务并返回值
希望线程返回一个结果
std::async是一个函数模版,用来启动一个异步任务,启动一个异步任务后,他返回一个std::future对象,std::futrue是一个类模版。
什么叫“启动一个异步任务”,就是自动创建一个线程并开始执行线程入口函数,它返回一个std::futrue对象
这个std::futrue对象里含有入口函数所返回的结果,我们可以通过调用futrue对象的成员函数get()来获取结果。
这个结果没法马上拿到,在将来的某个时刻可以拿到。
程序会卡在get,直到子线程执行结束并返回值,所以一定要有返回值。
2. std::packaged_task
打包任务,把任务包装起来
是一个类模版,它的模版参数是各种可调用对象;通过std::packaged_task把各种可调用对象包装起来,方便将来作为线程入口函数
3. std::promise
类模版,可以在某个线程中给它复制,然后我们可以在其他线程中,把这个值取出来。
void mythread(std::promise<int> &tmpp, int calc)
{
calc++;
calc*=10;
std::chrono::milliseconds dura(5000);
int result = calc;
tmpp.set_value(result);
return;
}
std::promise<int> myprom;
std::thread tl(mythread, std::ref(prom),180);
std::futrue<int> ful = myprom.get_future();
cout<<ful.get<<endl;
4. 小结
2020-03-05 09:35:05
来源:condition_variable、wait、notify_one、notify_all 查看详情
1. 条件变量std::condition_variable\wait()\notify_one()
std::condition_variable my_cond;
my_cond.wait(subguard1,[this]{
if(!msgRecvQue.empty()){
return true;
}
return false;
})
//wait()用来等一个东西
//如果第二个参数lambda表达式返回值是true,那wait()直接返回;
//如果第二个参数lambda表达式返回值是false,那wait()互斥量将解锁,并堵塞到本行。直到其他线程调用notify_once成员函数为止。
//如果没有第二个lambda函数,就和返回false一样。
//当其他线程使用notify_once
//b.1 mycond尝试获得锁,获得之后执行后续代码
//b.2如果没获得锁,就继续休眠
//b.3如果没有第二个参数,则和返回true一样。
注意:notify_one不是每次都能唤醒wait,只有在wait堵塞时才能成功唤醒。
std::unique_lock<mutex> subguard1(mymutex);
2.上述代码思考
消息会不会执行的不及时
消息在执行时notify_one无效,因为没有卡在wait();
3.notify_all()
notify_one只能通知一个线程。
notify_all通知多个线程。
没有更多了