2019.5.6 多线程学习

++ STL中哈希表 hash_map从头到尾详细介绍[转]

https://www.cnblogs.com/evidd/articles/8821349.html

C++ 二叉树的先序,中序,后序遍历

https://www.cnblogs.com/SunZhR/p/6594168.html

动态规划

状态,转移方程
https://www.jianshu.com/p/9847cc371858

贪婪算法

https://blog.youkuaiyun.com/a8082649/article/details/82079779


并发

[c++11]多线程编程(一)——初识

https://segmentfault.com/a/1190000016171072
在多核CPU上,能够真正的同时执行多个任务,称为硬件并发(hardware concurrency)。
多进程并发:将应用程序分为多个独立的、单线程的进程
多线程并发:一个进程中的所有线程都共享相同的地址空间,线程间的大部分数据都可以共享。线程间的通信一般都通过共享内存来实现。

任务并行(task parallelism)
数据并行(data parallelism)

多线程库对应的头文件是#include <thread>,类名为std::thread
任何程序都是一个进程,main()函数就是其中的主线程.
一旦线程开始运行, 就需要显式的决定是要等待它完成(join),或者分离它让它自行运行(detach)。注意:只需要在std::thread对象被销毁之前做出这个决定。

守护线程
线程被分离之后,即使该线程对象被析构了,线程还是能够在后台运行,只是由于对象被析构了,主线程不能够通过对象名与这个线程进行通信。
一旦一个线程被分离了,就不能够再被join了。如果非要调用,程序就会崩溃,可以使用**joinable()**函数判断一个线程对象能否调用join()。

youtube 视频网址
https://www.youtube.com/watch?v=LL8wkskDlbs&list=PL5jc9xFGsL8E12so1wlMS0r0hTQoJL74M&index=1

[c++11]多线程编程(二)——理解线程类的构造函数

https://segmentfault.com/a/1190000016186741
std::thread类的构造函数是使用可变参数模板实现的,可以传递任意个参数,第一个参数是线程的入口函数,而后面的若干个参数是该函数的参数。
可调用对象。
如果可以想真正传引用,可以在调用线程类构造函数的时候,用std::ref()包装一下。
构造函数的第一个参数是可调用对象,默认情况下其实传递的还是一个副本。
线程对象之间是不能复制的,只能移动,即将线程的所有权在std::thread实例间进行转移。

[c++11]多线程编程(三)——竞争条件与互斥锁

https://segmentfault.com/a/1190000016201729
所有线程之间共享数据的问题,都是修改数据导致的。

在c++中,可以使用互斥锁std::mutex进行资源保护,头文件是#include <mutex>,共有两种操作:锁定(lock)与解锁(unlock)。
果mu.lock()和mu.unlock()之间的语句发生了异常,unlock()语句没有机会执行!导致mu一直处于锁着的状态。
RAII技术,即获取资源即初始化(Resource Acquisition Is Initialization)技术,在类的构造函数中创建资源,在析构函数中释放资源。c++库已经提供了std::lock_guard类模板。
1.不要提供函数让用户获取资源。
2.不要将资源传递给用户的函数。

STL中的stack类是线程不安全的,接口设计不当引起的竞争。

[c++11]多线程编程(四)——死锁(Dead Lock)

https://segmentfault.com/a/1190000016217199
当一个操作需要使用两个互斥元的时候,仅仅使用lock_guard并不能保证不会发生死锁。
严格规定上锁顺序。
c++标准库中提供了std::lock()函数,能够保证将多个互斥锁同时上锁。
因为互斥锁已经被上锁了,那么lock_guard构造的时候不应该上锁,只是需要在析构的时候释放锁就行了,使用
std::adopt_lock
表示无需上锁。

[c++11]多线程编程(五)——unique_lock

https://segmentfault.com/a/1190000016231595
互斥锁保证了线程间的同步,但是却将并行操作变成了串行操作,对性能有很大的影响,所以要尽可能减小锁定的区域,也就是使用细粒度锁
使用unique_lock。它提供了lock()和unlock()接口,能记录现在处于上锁还是没上锁状态,在析构的时候,会根据当前状态来决定是否要进行解锁(lock_guard就一定会解锁)。
可以使用std::defer_lock设置初始化的时候不进行默认的上锁操作。
unique_lock和lock_guard都不能复制,lock_guard不能移动,但是unique_lock可以。

[c++11]多线程编程(六)——条件变量(Condition Variable)

https://segmentfault.com/a/1190000016237763
条件变量(condition variable),c++11中提供了#include <condition_variable>头文件,其中的std::condition_variable可以和std::mutex结合一起使用,其中有两个重要的接口,notify_one()和wait()。
**wait()**可以让线程陷入休眠状态。
**notify_one()**就是唤醒处于wait中的其中一个条件变量(可能当时有很多条件变量都处于wait状态)。
wait()函数会先调用互斥锁的unlock()函数,然后再将自己睡眠,在被唤醒后,又会继续持有锁。
在notify_one()的时候,不需要处于互斥锁的保护范围内。
**notify_all()**函数,可以同时唤醒所有处于wait状态的条件变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值