c++多线程编程
c++线程库:创建线程:需要可调用的函数或者函数对象作为线程入口点
例:std::thread threadname ( function_name , args...)
[*]在C++中,当使用std::thread创建线程并传递类的成员函数时,需要使用&来获取成员函数的地址,同时还需要传递对象的指针(或引用)作为第一个参数。
例:(A为一个类,a为A的一个实例化对象) thread t (&A::func_name,&a,args)
增补:在使用多线程编程时,内存管理变得更加复杂,使用智能指针可以帮助我们更好避免内存泄漏
auto_ptr 是c++ 98定义的智能指针模板,其定义了管理指针的对象,可以将new 得到(直接或间接)的地址赋给这种对象。当对象过期时,其析构函数将使用delete 来开释内存
头文件:#include < memory >
[*]【c++11已过期】auto_ptr 变量名(new 类型)
·ptr.get() //获取智能指针托管的指针地址
·ptr.release() //取消智能指针对动态内存的托管
·ptr.reset(arg) //将参数的指针(不指定则为NULL),与托管的指针比较,假如地址不一致,那么就会析构掉原来托管的指针,然后使用参数的指针替换之
[*]auto_ptr 主要有三大问题:
· 复制和赋值会改变资源的全部权,不符合人的直觉。
· 在 STL 容器中使用auto_ptr存在风险,因为容器内的元素必需支持可复制和可赋值。
· 不支持对象数组的操纵
因此c++11后使用unique_ptr shared_ptr和weak_ptr取代
[*]unique_ptr
函数:
thread.join(); //执行join后,等待线程完成函数,主线程需要等待子线程运行结束了才可以结束
thread.detach(); //执行detach可以分离子线程,主线程不会等待子线程运行结束才结束
thread.joinable();//会返回一个bool值,判断是否已经使用过join或者detach *已调用时返回false*
std::ref(para); //thread的方法传递引用的时候,必须外层用ref来进行引用传递,否则会编译出错调用类内私有成员函数:友元函数
例: void func_name();需要调用类内的私有成员函数
则在类内需要通过声明 friend void func_name();
c++11 互斥量
[*]头文件:#include
[*]根本互斥类: mutex _name;
[*]构造函数:mutex不允许拷贝构造,也不允许move拷贝,最初产生的mutex对象处于unlocked状态
[*]lock():调用线程将锁住该互斥量,线程调用该函数会发生以下3种环境:
(1) 假如该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用unlock之前,该线程一直拥有该锁。
(2) 假如当前互斥量被其他线程锁住,则当前的调用线程被壅闭住。
(3) 假如当前互斥量被当前调用线程锁住,则会产生死锁,,也就是说同一个线程中不允许锁两次。
[*]try_lock():尝试锁住互斥量,假如互斥量被其他线程占有,则当前线程也不会被壅闭,线程调用该函数会出现下面3种环境:
(1) 假如当前互斥量没有被其他线程占有,则该线程锁住互斥量,直到该线程调用unlock开释互斥量。
(2) 假如当前互斥量被其他线程锁住,则当前调用线程返回false,而并不会被壅闭掉。
(3) 假如当前互斥量被当前调用线程锁住,则会产生死锁。
[*]递归互斥类【能进行多次锁定而不造成死锁】: recursive_mutex
[*]与mutex类似,但是能够进行多次lock,能够规避一些死锁问题
[*]定时互斥类【可以锁定一定的时间】:time_mutex
[*]定时递归互斥类:recursive_timed_mutex;
互斥量死锁
[*]lock_guard: c++标准库互斥量封装类,用于掩护共享数据,防止多个线程同时访问统一资源而导致的数据竞争
[*]构造函数调用时,该互斥量主动锁定
[*]析构函数调用时,该互斥量主动解锁
例:lock_guard< Template > lock_name(obj);
[*]lock_guard类是 non-copyable的。
[*]unique_lock: 可以对互斥量进行更加灵活管理,包罗延迟加锁、条件变量、超时等
[*]成员函数:
(1) lock() 尝试对互斥量加锁,若加锁失败则壅闭直到乐成加锁
(2) try_lock() 尝试枷锁,乐成返回true,失败返回false
condition_variable及其使用场景
[*]头文件#include
[*]条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包罗两个动作:一个线程等待条件变量的条件成立而挂起;另一个线程使条件成立(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥量结合在一起。【常见用途:生产者-消费者模型】
[*]从条件变量的作用可以知道,在使用条件变量时,分为两个方面:
(1) 用于关照已壅闭线程,共享变量已改变
(2) 用于壅闭某一线程,直至该线程被唤醒
[*]创建:condition_variable cv_name;
[*]cv_obj.wait(unique_lock_obj,arg) 消费者在共享资源不足时,通过wait函数等待,第二个参数arg为true时不等待,false时壅闭等待。
当前线程调用wait()后将被壅闭,直到别的某个线程调用notify_唤醒当前线程;当线程被壅闭时,该函数会主动调用std::mutex的unlock()开释锁,使得其它被壅闭在锁竞争上的线程得以继续执行。一旦当前线程得到关照(notify,通常是别的某个线程调用notify_唤醒了当前线程),wait()函数也是主动调用std::mutex的lock()。wait分为无条件被壅闭和带条件的被壅闭两种。
[*]cv_obj.notify_one()唤醒某个等待(wait)线程。假如当前没有等待线程,则该函数什么也不做,假如同时存在多个等待线程,则唤醒某个线程是不确定的
[*]cv_obj.notify_all() 唤醒全部等待进程
[*]notify_all_at_thread_exit 当调用该函数的线程退出时,全部在 cond 条件变量上等待的线程都会收到关照
condition_variable_any 先容
与 condition_variable 类似,只不过 condition_variable_any 的 wait 函数可以接受任何 lockable 参数,而condition_variable 只能接受 unique_lock< mutex > 类型的参数,除此以外,和 :condition_variable 几乎完全一样。
异步并发
1. async、future
[*]头文件: #include
[*]c++11引入的函数模板,用于异步执行一个函数,并返回到future对象,表示异步操纵的结果。使用async可以方便进行异步编程,避免了手动创建和管理线程的麻烦
例:std::future< template > future_name = std::async(std::launch::async, func_name);
2. packaged_task
[*]类模板,用于将一个可调用对象(如函数、函数对象或Lambda表达式)封装为一个异步操纵,并返回一个future对象,表示异步操纵结果。package_task可以方便将一个函数或可调用对象转换为一个异步操纵,供其他线程使用
例: std::packaged_task task_name(func_name);
// 此时得到的是封装好的task对象,需要通过创建线程执行 【记得使用move(task)把可移动对象放入线程执行】
auto result = task_name.get_future();
3. promise
[*]用于在线程中产生一个值,并在另一个线程中获取该值。通常与future和async一起使用,实现异步编程。
[*]创建:std::promise name
[*]获取值: name.get_future();+result.get()
原子操纵:atomic
[*]c++11标准库中的一个模板类,用于实现多线程编程环境下的原子操纵。提供一种线程安全的方式访问和修改共享变量,可以避免多线程环境中的数据竞争问题
[*]头文件: #include
[*]创建: std::atomic data_name
[*]相较于加锁实现的互斥,在线程安全中,原子操纵的性能更好
[*]常见std::atomic操纵:
load(): 将std::atomic变量的值加载到当前线程的本地缓存中并返回
store(value): 将value的值存储到std::atomic变量中,这个操纵是原子性的
exchange(value): 将value的值存储到std::atomic变量中,并返回原先的值
compare_exchange_weak(expected, val) 和 compare_exchange_strong(expected, val):比较 std::atomic 变量的值和 expected 的值是否相同,假如相同,则将 val 的值存储到 std::atomic 变量中,并返回 true;否则,将 std::atomic 变量的值存储到 expected 中,并返回 false。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]