Boost文档:第27章:线程(二)
2011年12月24日
Anthony Williams Copyright?? 2007-8 Anthony Williams Distributed under the Boost Software License,Version 1.0.(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 同步
4.1 互斥概念
互斥对象让数据竞争保护变得容易,使得对数据的线程安全同步成为可能。线程通过调用互斥对象的某个锁函数来获取所有权,通过调用相应的解锁函数来释放所有权。互斥量可以是递归的,也可以是非递归的,并且可能给一个或者多个线程同时授予所有权。Boost.Thread提供了带独占所有权语义的递归和非递归的互斥量,以及共享所有权(多个读/单个写)互斥量。
Boost.Thread支持四种基本的可锁定对象概念:Lockable、TimedLockable、SharedLockable和UpgradeLockable。每个互斥量类型和各种锁类型实现了这些概念中的一个或者多个。 4.1.1 Lockable概念
Lockable概念是独占所有权的模型。实现Lockable概念的类型需要提供下述成员函数:
必须调用unlock()来释放调用lock()或者try_lock()取得的所有权。
void lock()
n 作用:阻塞当前线程,直到可以获取所有权。
n 后置条件:当前线程拥有*this
n 异常:发生错误时抛出boost::thread_resource_error。
bool try_lock()
n 作用:试图为当前线程获取所有权,不阻塞。
n 返回:如果当前线程取得了所有权则返回true,否则返回false。
n 后置条件:如果返回true,当前线程拥有*this。
n 异常:发生错误时抛出boost::thread_resource_error。
void unlock()
n 前提条件:当前线程拥有*this。
n 作用:释放当前线程的所有权。
n 后置条件:当前线程不再拥有*this。
n 异常:无。 4.1.2 TimedLockable概念
TimedLockable概念改进了Lockable概念,增加了试图获取锁时的超时支持。
实现TimedLockable概念的类型必须满足Lockable概念的要求。此外还必须提供下述函数:
必须调用unlock()来释放调用timed_lock()取得的所有权。
bool timed_lock(boost::system_time const & abs_time)
n 作用:试图为当前线程获取所有权。阻塞当前线程,直到可以取得所有权,或者经过指定的时间。如果已经经过指定的时间,则行为同try_lock()。
n 返回:如果当前线程取得了所有权则返回true,否则返回false。
n 后置条件:如果返回true,当前线程拥有*this。
n 异常:发生错误时抛出boost::thread_resource_error。
template bool timed_lock(DurationType const& rel_time)
n 作用:等同于timed_lock(boost::get_system_time() + rel_time) 4.1.3 SharedLockable概念
SharedLockable概念改进了TimedLockable概念,同时支持独占所有权和共享所有权。采用的是标准多个读/单个写模型:至多只有一个线程拥有独占所有权,如果任何线程拥有独占所有权,则没有其他线程可以拥有共享或者独占所有权。或者,多个线程可以同时拥有共享所有权。
实现SharedLockable概念的类型除了要满足TimedLockable概念的要求外,还必须提供下述成员函数:
必须调用unlock_shared()释放调用lock_shared()、try_lock_shared()或者timed_lock_shared()取得的所有权。
void lock_shared()
n 作用:阻塞当前线程,直到可以取得所有权。
n 后置条件:当前线程拥有*this的共享所有权。
n 异常:发生错误时抛出boost::thread_resource_error。
bool try_lock_shared()
作用:试图为当前线程获取共享所有权,不阻塞。
n 返回:如果当前线程取得了所有权则返回true,否则返回false。
n 后置条件:如果返回true,当前线程拥有*this的共享所有权。
n 异常:发生错误时抛出boost::thread_resource_error。
bool timed_lock_shared(boost::system_time const& abs_time)
n 作用:试图为当前线程获取所有权。阻塞当前线程,直到可以取得所有权,或者经过指定的时间。如果已经经过指定的时间,则行为同try_lock_shared()。
n 返回:如果当前线程取得了共享所有权则返回true,否则返回false。
n 后置条件:如果返回true,当前线程拥有*this的共享所有权。
n 异常:发生错误时抛出boost::thread_resource_error。
void unlock_shared()
n 前提条件:当前线程拥有*this的共享所有权。
n 作用:释放当前线程对*this的共享所有权。
n 后置条件:当前线程不再拥有*this的共享所有权。
n 异常:无 4.1.4 UpgradeLockable概念
UpgradeLockable概念改进了SharedLockable概念,除了支持独占所有权和共享所有权之外,还支持可升级的所有权。这是对SharedLockable概念提供的多个读/单个写模型的扩展:多个线程拥有共享所有权的时候,单个线程可拥有可升级的所有权。拥有可升级所有权的线程可以在任何时候试图升级到独占所有权。如果此时没有其他线程拥有共享所有权,则升级会立即完成,线程拥有独占所有权。必须调用unlock()来释放取得的独占所有权,就像释放调用lock()获取的独占所有权一样。
如果拥有可升级所有权的线程在试图升级的时候,有其他线程拥有共享所有权,则升级企图会失败,线程被阻塞,直到可以取得独占所有权。
就像可以升级一样,所有权也可以降级:UpgradeLockable概念实现的独占所有权可以降级成可升级所有权或者共享所有权,可升级所有权可以降级成共享所有权。
实现UpgradeLockable概念的类型除了要满足SharedLockable概念的要求之外,还必须提供下述成员函数:
必须调用unlock_upgrade()来释放调用lock_upgrade()取得的所有权。如果调用unlock_xxx_and_lock_yyy()函数改变了所有权类型,则必须调用新的所有权等级对应的解锁函数来释放所有权。
void lock_upgrade()
n 作用:阻塞当前线程,直到取得可升级所有权。
n 后置条件:当前线程拥有*this的可升级所有权。
n 异常:发生错误时抛出boost::thread_resource_error。
void unlock_upgrade()
n 前提条件:当前线程拥有*this的可升级所有权。
n 作用:释放当前线程的可升级所有权。
n 后置条件:当前线程不再拥有*this的可升级所有权。
n 异常:无。
void unlock_upgrade_and_lock()
n 前提条件:当前线程拥有*this的可升级所有权。
n 作用:原子地释放当前线程拥有的对*this的可升级所有权,获取对*this的独占所有权。如果有其他线程当前拥有共享所有权,则阻塞直到可以取得独占所有权。
n 后置条件:当前线程拥有*this的独占所有权。
n 异常:无。
void unlock_upgrade_and_lock_shared()
n 前提条件:当前线程拥有*this的可升级所有权。
n 作用:原子地释放当前线程拥有的对*this的可升级所有权,请求共享所有权,不阻塞。
n 后置条件:当前线程拥有*this的共享所有权。
n 异常:无。
void unlock_and_lock_upgrade()
n 前提条件:当前线程拥有*this的独占所有权。
n 作用:原子地释放当前线程拥有的对*this的独占所有权,请求可升级所有权,不阻塞。
n 后置条件:当前线程拥有*this的可升级所有权。
n 异常:无。 4.2 锁类型
4.2.1 lock_guard模板类
boost::lock_guard非常简单:构造函数请求获取参数提供的Lockable概念实现的所有权。析构函数释放所有权。这提供了简单的对Lockable对象的RAII风格的锁,使得线程安全的锁定和解锁变得容易。此外,构造函数lock_guard(Lockable & m,boost::adopt_lock_t)可获取已经由当前线程持有的锁的所有权。
lock_guard(Lockable & m)
n 作用:存储对m的引用,调用m.lock()。
n 异常:抛出由m.lock()产生的异常。
lock_guard(Lockable & m,boost::adopt_lock_t)
n 前提条件:当前线程拥有等价于调用m.lock()取得的、对m的锁。
n 作用:存储对m的引用,取得对m锁定状态的所有权。
n 异常:无。
~lock_guard()
n 作用:对构造函数传入的Lockable对象调用unlock()。
n 异常:无。 4.2.2 unique_lock模板类
boost::unique_lock比boost::lock_guard更复杂:因为它不仅仅提供一个RAII风格的锁,还允许延迟锁定请求到显式调用成员函数lock()的时候,允许试图以非阻塞的方式请求锁,允许带有请求超时。结果,只有在锁对象已经锁住Lockable对象时,析构函数才会调用unlock(),或者采用Lockable对象上的锁。
如果提供的Lockable类型模型化了TimedLockable概念(如boost::unique_lock::timed_mutex>)或者Lockable概念(boost::unique_lock::mutex>),则特化的boost::unique_lock也模型化了TimedLockable概念或者Lockable概念。
如果一个boost::unique_lock实例的mutex()函数返回指向Lockable m的指针,owns_lock()返回true,则称这个实例是拥有Lockable m的锁状态的。拥有Lockable对象锁状态的对象销毁时,其析构函数会调用mutex()->unlock()。
boost::unique_lock的成员函数不是线程安全的。特别是,boost::unique_lock是设计用于模型化某特定线程对某Lockable对象的所有权的,释放锁状态所有权的成员函数(包括析构函数)必须由获取锁状态的相同线程调用。
unique_lock()
n 作用:创建一个没有与互斥量关联的锁对象。
n 后置条件:owns_lock()返回false,mutext()返回NULL。
n 异常:无。
unique_lock(Lockable & m)
n 作用:存储m的引用,调用m.lock()。
n 后置条件:owns_lock()返回true,mutex()返回&m。
n 异常:m.lock()抛出的任何异常。
unique_lock(Lockable& m,boost::adopt_lock_t)
n 前提条件:当前线程拥有m的独占锁。
n 作用:存储m的引用,取得m的锁状态的所有权。
n 后置条件:owns_lock()返回true,mutex()返回&m。
n 异常:无。
unique_lock(Lockable& m,boost::defer_lock_t)
n 作用:存储m的引用。
n 后置条件:owns_lock()返回false,mutex()返回&m。
n 异常:无。
unique_lock(Lockable & m,boost::try_to_lock_t)
n 作用:存储m的引用,调用m.try_lock(),如果返回true,则取得锁状态的所有权。
n 后置条件:mutex()返回&m。如果try_lock()返回true,则owns_lock()返回true,否则owns_lock()返回false。
n 异常:无。
unique_lock(Lockable& m,boost::system_time const & abs_time)
n 作用:存储m的引用,调用m.timed_lock(abs_time),如果返回true,则取得锁状态的所有权。
n 后置条件:mutex()返回&m。如果timed_lock()返回true,则owns_lock()返回true,否则owns_lock()返回false。
n 异常:任何由m.timed_lock(abs_time)抛出的异常。
~unique_lock()
n 作用:如果owns_lock()返回true,则调用mutex()->unlock()。
n 异常:无。
bool owns_lock() const
n 返回:如果*this拥有与自身关联的Lockable对象的锁,则返回true。
n 异常:无。
Lockable* mutex() const
n 返回:与*this关联的Lockable对象的指针,或者,没有关联的对象时,返回NULL。
n 异常:无。
operator unspecified_bool_type() const
n 返回:如果owns_lock()返回true,则返回一个在布尔上下文中与true等价的值,否则返回一个在布尔上下文中与false等价的值。
n 异常:无。
bool operator!() const
n 返回:!owns_lock()
n 异常:无。
Lockable* release()
n 作用:移除*this与Lockable对象的关联,而不影响Lockable对象的锁状态。如果owns_lock()返回true,则确保正确解锁Lockable对象是调用代码的责任。
n 返回:返回调用时与*this关联的Lockable对象指针,或者,没有关联的对象时返回NULL。
n 异常:无。
n 后置条件:*this不再与任何Lockable对象关联。mutex()返回NULL,owns_lock()返回false。 4.2.3 shared_lock模板类
与boost::unique_lock一样,boost::shared_lock模型化Lockable概念,不同的是,boost::shared_lock请求获取指定的Lockable对象的共享所有权,而不是唯一所有权。锁定一个boost::shared_lock实例请求的是共享所有权。
与boost::unique_lock不仅仅提供RAII风格的锁一样,boost::shared_lock也允许延迟锁定到显式调用成员函数lock()时,允许以非阻塞的方式试图获取锁,允许带有超时。结果,只有在锁对象已经锁住Lockable对象的时候,析构函数才会调用unlock(),否则则采用Lockable对象上的锁。
如果一个boost::shared_lock实例的mutex()函数返回指向Lockable m的指针,owns_lock()返回true,则称这个实例是拥有Lockable m的锁状态的。拥有Lockable对象锁状态的对象销毁时,其析构函数会调用mutex()->unlock_shared()。
boost::shared_lock的成员函数不是线程安全的。特别是,boost::shared_lock是设计用于模型化某特定线程对某Lockable对象的共享所有权的,释放锁状态所有权的成员函数(包括析构函数)必须由获取锁状态的相同线程调用。
shared_lock()
n 作用:创建一个没有与互斥量关联的锁对象。
n 后置条件:owns_lock()返回false,mutex()返回NULL。
shared_lock(Lockable& m)
n 作用:存储m的引用,调用m.lock_shared()。
n 后置条件:owns_lock()返回true,mutex()返回&m。
n 异常:m.lock_shared()抛出的任何异常。
shared_lock(Lockable& m,boost::adopt_lock_t)
n 前提条件:当前线程拥有m的独占锁。
n 作用:存储m的引用,取得m锁状态的所有权。
n 后置条件:owns_lock()返回true,mutex()返回&m。
n 异常:无。
shared_lock(Lockable& m,boost::defer_lock_t)
n 作用:存储m的引用。
n 后置条件:owns_lock()返回false,mutex()返回&m。
n 异常:无。
shared_lock(Lockable& m,boost::try_to_lock_t)
n 作用:存储m的引用,调用m.try_lock_shared(),如果返回true,则取得锁状态的所有权。
n 后置条件:mutex()返回&m。如果try_lock_shared()返回true,则owns_lock()返回true,否则owns_lock()返回false。
n 异常:无。
shared_lock(Lockable& m,boost::system_time const & abs_time)
n 作用:存储m的引用,调用m.timed_lock(abs_time),如果返回true,则取得锁状态的所有权。
n 后置条件:mutex()返回&m。如果timed_lock_shared()返回true,则owns_lock()返回true,否则owns_lock()返回false。
n 异常:m.timed_lock(abs_time)返回的任何异常。
~shared_lock()
n 作用:如果owns_lock()返回true,则调用mutex()->unlock_shared()。
n 异常:无。
bool owns_lock() const
n 返回:如果拥有与*this关联的Lockable对象的锁,则返回true。
n 异常:无。
Lockable* mutex() const
n 返回:与*this关联的Lockable对象的指针,或者,没有关联的对象时,返回NULL。
n 异常:无。
operator unspecified_bool_type() const
n 返回:如果owns_lock()返回true,则返回一个在布尔上下文中与true等价的值,否则返回一个在布尔上下文中与false等价的值。
n 异常:无。
bool operator!() const
n 返回:!owns_lock()
n 异常:无。
Lockable* release()
n 作用:移除*this与Lockable对象的关联,而不影响Lockable对象的锁状态。如果owns_lock()返回true,则确保正确解锁Lockable对象是调用代码的责任。
n 返回:返回调用时与*this关联的Lockable对象指针,或者,没有关联的对象时返回NULL。
n 异常:无。
n 后置条件:*this不再与任何Lockable对象关联。mutex()返回NULL,owns_lock()返回false。 4.2.4 upgrade_lock模板类
与boost::unique_lock一样,boost::upgrade_lock模型化Lockable概念,但不是请求Lockable对象的唯一所有权,而是请求可升级所有权。
与boost::unique_lock不仅仅提供RAII风格的锁一样,boost::upgrade_lock允许延迟请求锁定到显式调用成员函数lock()时,允许以非阻塞方式试图获取锁,允许带有超时。结果,只有在锁对象已经锁住Lockable对象的时候,析构函数才会调用unlock(),否则则采用Lockable对象上的锁。
如果一个boost::upgrade_lock实例的mutex()函数返回指向Lockable m的指针,owns_lock()返回true,则称这个实例是拥有Lockable m的锁状态的。拥有Lockable对象锁状态的对象销毁时,析构函数会调用mutex()->unlock_upgrade()。
boost::upgrade_lock的成员函数不是线程安全的。特别是,boost::upgrade_lock是设计用于模型化某特定线程对某Lockable对象的可升级所有权的,释放锁状态所有权的成员函数(包括析构函数)必须由获取锁状态的相同线程调用。 4.2.5 upgrade_to_unique_lock
boost::upgrade_to_unique_lock允许临时升级boost::upgrade_lock到独占所有权。构造boost::upgrade_to_unique_lock的时候,如果使用的boost::upgrade_lock引用拥有某Lockable对象的可升级所有权,则会升级到独占所有权。销毁boost::upgrade_to_unique_lock实例时,对Lockable对象的所有权降级到可升级所有权。 4.2.6 互斥量特定的类scoped_try_lock
为每个MutexType提供了作为成员typedef的scoped_try_lock。每个构造函数和成员函数的语义与具有相同MutexType的boost::unique_lock的相应函数相同,只是带有单个互斥量引用m的构造函数将调用m.try_lock(),而不是m.lock()。 4.3 锁函数
4.3.1 非成员函数lock(Lockable1,Lockable2,...)
n 作用:以可避免死锁的、非特定的、不确定的次序锁定作为参数提供的Lockable对象。以不同的次序在多个线程中并发地对相同互斥量(或者其他可锁定对象)调用这个函数是安全的,没用死锁的风险。如果对提供的任何Lockable对象的lock()或者try_lock()操作抛出异常,则函数退出前会释放所有先前已经取得的锁。
n 异常:对提供的Lockable对象调用lock()或者try_lock()时抛出的任何异常。
n 后置条件:提供的所有Lockable对象都被调用线程锁定。 4.3.2 非成员函数lock(begin,end)
n 前提条件:ForwardIterator的值类型必须实现了Lockable概念。
n 作用:以可避免死锁的、非特定的、不确定的次序锁定指定范围内的所有Lockable对象。以不同的次序在多个线程中并发地对相同互斥量(或者其他可锁定对象)调用这个函数是安全的,没用死锁的风险。如果对提供的任何Lockable对象的lock()或者try_lock()操作抛出异常,则函数退出前会释放所有先前已经取得的锁。
n 异常:对提供的Lockable对象调用lock()或者try_lock()时抛出的任何异常。
n 后置条件:指定范围内的所有Lockable对象都被调用线程锁定。 4.3.3 非成员函数try_lock(Lockable1,Lockable2,...)
n 作用:对作为参数提供的每个Lockable对象调用try_lock()。如果任何一个try_lock()返回false,则释放先前已经取得的所有锁,返回锁定失败对象的从零开始的索引。
n 如果对提供的任何Lockable对象的try_lock()操作抛出异常,则函数退出前会释放所有先前已经取得的锁。
n 异常:对提供的Lockable对象调用try_lock()时抛出的任何异常。
n 后置条件:如果返回-1,则提供的所有Lockable对象都被调用线程锁定。否则,任何已经被函数取得的锁都会被释放。 4.3.4 非成员函数try_lock(begin,end)
n 前提条件:ForwardIterator的值类型必须实现了Lockable概念。
n 作用:对指定范围内的每个Lockable对象调用try_lock()。如果任何一个try_lock()调用返回false,则任何已经取得的锁都会被释放,然后返回锁定失败的对象的迭代器。
n 如果对提供的任何Lockable对象的try_lock()操作抛出异常,则函数退出前会释放所有先前已经取得的锁。
n 返回:如果返回end,则指定范围内的所有Lockable对象都已经被调用线程锁定。否则,任何已经被函数取得的锁都会被释放。 4.4 互斥量类型
4.4.1 mutex类
boost::mutex实现了Lockable概念,提供一个独占所有权的互斥量。任何时刻只能有一个线程拥有某给定的boost::mutex的所有权。多个线程可以并发地调用lock()、try_lock()和unlock()。
成员函数native_handle()
n 作用:返回一个native_handle_type实例,可用于平台特定的API,以操作底层实现。如果没有这种实例,则native_handle()和native_handle_type是不存在的。
n 异常:无。 4.4.2 typedef try_mutex
boost::try_mutex是boost::mutex的typedef,以提供对先前的boost版本的向后兼容性。 4.4.3 timed_mutex
boost::timed_mutex实现了TimedLockable概念,提供一个独占所有权的互斥量。任何时刻只能有一个线程拥有某给定的boost::timed_mutex的所有权。多个线程可以并发地调用lock()、try_lock()和unlock()。
成员函数native_handle()
n 作用:返回一个native_handle_type实例,可用于平台特定的API,以操作底层实现。如果没有这种实例,则native_handle()和native_handle_type是不存在的。
n 异常:无。 4.4.4 recursive_mutex类
boost::recursive_mutex实现了Lockable概念,提供一个独占所有权的互斥量。任何时刻只能有一个线程拥有某给定的boost::recursive_mutex的所有权。多个线程可以并发地调用lock()、try_lock()和unlock()。已经拥有某boost::recursive_mutex实例的所有权的线程可以调用lock()和try_lock()以获取额外的所有权级别。对于单个线程取得的每个级别的所有权,都必须调用unlock(),只有这样,其他线程才可以取得所有权。
成员函数native_handle()
n 作用:返回一个native_handle_type实例,可用于平台特定的API,以操作底层实现。如果没有这种实例,则native_handle()和native_handle_type是不存在的。
n 异常:无。 4.4.5 recursive_try_mutex
boost::recursive_try_mutex是boost::recursive_mutex的typedef,以提供对先前的boost版本的向后兼容性。 4.4.6 recursive_timed_mutex类
boost::recursive_timed_mutex实现了TimedLockable概念,提供一个独占所有权的互斥量。任何时刻只能有一个线程拥有某给定的boost::recursive_timed_mutex实例的锁。多个线程可以并发地调用lock()、try_lock()、timed_lock()和unlock()。已经拥有某boost::recursive_timed_mutex实例的独占所有权的线程可以调用lock()、timed_lock()和try_lock()以获取额外的所有权级别。对于单个线程取得的每个级别的所有权,都必须调用unlock(),只有这样,其他线程才可以取得所有权。
成员函数native_handle()
n 作用:返回一个native_handle_type实例,可用于平台特定的API,以操作底层实现。如果没有这种实例,则native_handle()和native_handle_type是不存在的。
n 异常:无。
4.4.7 shared_mutex类
boost::shared_mutex实现了多个读/单个写的互斥量。它实现了UpgradeLockable概念。
多个线程可以并发地调用lock()、try_lock()、timed_lock()、lock_shared()、try_lock_shared()和timed_lock_shared()。 4.5 条件变量
4.5.1 概述
condition_variable和condition_variable_any提供了一种机制,让一个线程可以等待某特定条件成为true时来自另一个线程的通知。通常的使用模式是,某线程锁定一个互斥量,然后对一个condition_variable或者condition_variable_any实例调用wait。在等待中被唤醒时,线程检查条件是否是true,如果是,则继续执行。如果条件还不是true,线程再次调用wait,继续等待。在最简单的情况下,条件仅仅是一个布尔值:
注意传递给wait函数的lock:wait函数原子地将线程添加到等待条件变量的线程集中,并且解锁互斥量。线程被唤醒时,在wait函数返回前,互斥量会再次被锁定。这让其他线程可以取得互斥量,更新共享数据,并且保证与条件关联的数据是正确同步的。
同时,另一个线程设置条件为true,对条件变量调用notify_one或者notify_all,分别唤醒一个或者所有等待线程。
注意,更新共享数据前相同的互斥量被锁定,但是调用notify_one的时候不需要保持锁定。
这个例子使用了condition_variable类型的对象,但是使用condition_variable_any类型的对象也是可以的:condition_variable_any更通用,可以与任何类型的锁或者互斥量一同工作,而condition_variable要求传递给wait函数的是boost::unique_lock::mutex>类型的实例。基于互斥量类型的知识,condition_variable可以在某些情况下进行一些优化;而condition_variable_any则通常有比condition_variable复杂的实现。 4.5.2 condition_variable类
condition_variable() n 作用:构造一个condition_variable对象。
n 异常:发生错误时抛出boost::thread_resource_error。
~condition_variable()
前提条件:所有等待*this的线程已经被notify_one或者notify_all通知(但相应的wait或者timed_wait调用不必已经返回)
n 作用:销毁对象。
n 异常:无。
void notify_one()
n 作用:如果当前有任何线程阻塞在对*this的wait或者timed_wait调用上,解锁等待线程中的一个。
n 异常:无。
void notify_all()
n 作用:如果当前有任何线程阻塞在对*this的wait或者timed_wait调用上,解锁所有等待线程。
n 异常:无。
void wait(boost::unique_lock::mutex>& lock)
n 前提条件:lock被当前线程锁定,并且没有其他线程当前在等待*this,或者在所有当前等待*this的线程中,提供给wait或者timed_wait调用的锁对象的mutex()成员函数,将与本次调用的lock->mutex()函数返回相同的值。
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。线程在被this->notify_one()或者this->notify_all()调用通知时解锁,或者假解锁。线程解锁后(无论何种原因),wait返回前,将再次调用lock.lock()请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
template
void wait(boost::unique_lock::mutex>& lock,predicate_type pred)
n 作用:等价于
bool timed_wait(boost::unique_lock::mutex>& lock,boost::system_time const & abs_time)
n 前提条件:lock被当前线程锁定,并且没有其他线程当前在等待*this,或者在所有当前等待*this的线程中,提供给wait或者timed_wait调用的锁对象的mutex()成员函数,将与本次调用的lock->mutex()函数返回相同的值。
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。被this->notify_one()或者this->notify_all()调用通知时,或者boost::get_system_time()报告的时间等于或迟于abs_time指定的时间时,或者假解锁时,线程退出阻塞状态。线程退出阻塞状态时(无论何种原因),在wait调用返回之前,会调用lock.lock()再次请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 返回:如果因为到达abs_time指定的时间而返回,则返回false,否则返回true。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
template
bool timed_wait(boost::unique_lock::mutex>& lock,duration_type const & rel_time)
n 前提条件:lock被当前线程锁定,并且没有其他线程当前在等待*this,或者在所有当前等待*this的线程中,提供给wait或者timed_wait调用的锁对象的mutex()成员函数,将与本次调用的lock->mutex()函数返回相同的值。
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。被this->notify_one()或者this->notify_all()调用通知时,或者参数rel_time指定的时间已经流逝时,或者假解锁时,线程退出阻塞状态。线程退出阻塞状态时(无论何种原因),在wait调用返回之前,会调用lock.lock()再次请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 返回:如果因为rel_time指定的时间已经流逝而返回,则返回false,否则返回true。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
n 注意:很难正确使用带有持续时间的timed_wait重载版本。多数情况下,使用带有断言的重载版本更好。
template
bool timed_wait(boost::unique_lock::mutex>& lock,boost::system_time const & abs_time,predicate_type pred)
n 作用:等价于
4.5.3 condition_variable_any类
condition_variable_any() 作用:构造一个condition_variable_any对象。
异常:发生错误时抛出boost::thread_resource_error。
~condition_variable_any()
前提条件:所有等待*this的线程已经被notify_one或者notify_all调用通知(但相应的wait或者timed_wait调用不必已经返回)
作用:销毁对象。
异常:无。
void notify_one()
n 作用:如果当前有任何线程阻塞在对*this的wait或者timed_wait调用上,解锁等待线程中的一个。
n 异常:无。
void notify_all()
n 作用:如果当前有任何线程阻塞在对*this的wait或者timed_wait调用上,解锁所有等待线程。
n 异常:无。
void wait(boost::unique_lock::mutex>& lock)
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。线程在被this->notify_one()或者this->notify_all()调用通知时解除阻塞,或者假解锁。解除阻塞后(无论何种原因),wait返回前,将再次调用lock.lock()请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
template
void wait(lock_type& lock,predicate_type pred)
n 作用:等价于
template
bool timed_wait(lock_type& lock,boost::system_time const & abs_time)
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。被this->notify_one()或者this->notify_all()调用通知时,或者boost::get_system_time()报告的时间等于或迟于abs_time指定的时间时,或者假解锁时,线程退出阻塞状态。线程退出阻塞状态时(无论何种原因),在wait调用返回之前,会调用lock.lock()再次请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 返回:如果因为到达abs_time指定的时间而返回,则返回false,否则返回true。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
template
bool timed_wait(lock_type& lock,duration_type const & rel_time)
n 作用:原子地调用lock.unlock(),并且阻塞当前线程。被this->notify_one()或者this->notify_all()调用通知时,或者参数rel_time指定的时间已经流逝时,或者假解锁时,线程退出阻塞状态。线程退出阻塞状态时(无论何种原因),在wait调用返回之前,会调用lock.lock()再次请求锁定。如果函数因为异常退出,也会调用lock.lock()再次请求锁定。
n 返回:如果因为rel_time指定的时间已经流逝而返回,则返回false,否则返回true。
n 后置条件:lock被当前线程锁定。
n 异常:发生错误时抛出boost::thread_resoure_error。如果对当前线程关联到的boost::thread对象执行interrupt()调用,则等待被中断,抛出boost::thread_interrupted。
n 注意:很难正确使用带有持续时间的timed_wait重载版本。多数情况下,使用带有断言的重载版本更好。
template
bool timed_wait(lock_type& lock,boost::system_time const & abs_time,predicate_type pred)
n 作用:等价于
4.5.4 typedef condition
typedef condition用于提供对先前boost版本的向后兼容性。 4.6 一次性初始化
boost::call_one提供了一种机制,可以保证初始化例程只执行一次,没有数据竞争或者死锁。 4.6.1 typedef once_flag
应该用BOOST_ONCE_INIT初始化boost::once_flag类型的对象:
4.6.2 非成员函数call_once
n 要求:Callable是可拷贝构造(CopyConstructible)的。func应该没有边效应,调用func副本的效果应该等价于调用原版的func。
n 作用:对相同once_flag对象的call_once调用被串行化。如果先前没有对once_flag对象进行过有效的call_once调用,则参数func(或者其副本)被调用。如果func没有抛出异常,正常返回,则对call_once的调用是有效的。如果抛出异常,则异常被传播给调用者。如果先前已经对once_flag对象进行过有效的call_once调用,则call_once会返回,不调用func。
n 同步:对一个once_flag对象的有效call_once调用的完成,将与后续对相同once_flag对象的call_once调用同步。
n 异常:如果不能到达预定义的效果,则抛出thread_resource_error;或者func抛出的任何异常。
n 注意:传递给call_once的函数不得对传入的once_flag对象调用call_once。这可能会导致死锁,或者两次调用传入的函数。解决办法是让第二次调用立即返回,但这要求代码知道自己是被递归调用的,并且可以处理call_once实际上不调用函数的情况,这样函数才能避免递归地调用call_once。
这个重载用于提供向后兼容性。call_once(func,flag)的效果应该与call_once(flag,func)的效果相同。 4.7 护栏(barrier)
护栏是一个简单的概念,也称作集结点(rendezvous),是多个线程间的同步点。护栏配置为用于特定数量(n)的线程。线程到达护栏时,必须等待所有n个线程都到达。一旦第n个线程到达,所有等待线程继续运行,护栏被复位。 4.7.1 barrier类
boost::barrier实例是不可复制、不可移动的。
构造函数
n 作用:构造一个用于count个线程的护栏。
n 异常:发生错误时抛出boost::thread_resource_error。
析构函数
n 前提条件:没有线程在等待*this。
n 作用:销毁*this。
n 异常:无。
成员函数wait
n 作用:阻塞直到count个线程对*this调用了wait。第count个线程调用wait时,所有等待线程解除阻塞,护栏被复位。
n 返回:每一批等待线程中仅有一个返回true,其他返回false。
n 异常:发生错误时抛出boost::thread_resource_error。 4.8 期货(future)
4.8.1 概述
期货库提供了一种处理异步期货值的方式,期货值可以由其他线程生成,或者由单个线程响应外部刺激生成,或者按需生成。
这种机制由四个模板类提供:boost::unique_future和boost::shared_future用于获取异步结果,boost::promise和boost::packaged_task用于生成异步结果。
一个boost::unique_future维持唯一一个到某结果的引用。可以使用移动构造函数或者移动赋值运算符在实例间转移所有权,但是至多只有一个实例可以维持到某给定异步结果的引用。结果准备好时,通过boost::unique_future::get()以右值引用的方式返回,可以移动或者赋值成合适的类型。
另一方面,多个boost::shared_future实例可能引用相同的结果。多个实例间可以自由地拷贝和赋值,boost::shared_future::get()返回的是常引用,所以多个boost::shared_future::get()是安全的。可以将一个boost::unique_future实例移动到boost::shared_future实例中,从而转移关联的异步结果的所有权,但是不能进行相反的移动。
可以单独等待期货,或者使用boost::wait_for_any()和boost::wait_for_all()函数。 4.8.2 创建异步值
可以通过boost::promise或者boost::packaged_task来设置期货的值。boost::packaged_task是一个包装了某函数或者可调用对象的可调用对象。被调用的时候,boost::packaged_task会调用所含的函数,使用返回值填充期货。常见问题“如何从某线程返回一个值?”的答案是:将需要执行的函数封装成boost::packaged_task,然后传递给线程构造函数。这样,从boost::packaged_task取得的期货就可用于获取返回值。如果被封装的函数抛出异常,则异常被存储到期货中,代替返回值。
boost::promise更底层一点:它直接提供一个函数,用于存储一个值或者异常到关联的期货中。因此期货可用于可能从多个源返回值的情况,或者单个操作产生多个值的情况。
4.8.3 等待回调和延迟期货
boost::promise和boost::packaged_task都支持将在等待回调。等待回调在线程阻塞在对某期货的wait()或者timed_wait()调用上的时候,在等待线程中被调用。该期货正在等待来自boost::promise或者boost::packaged_task的结果。这可通过对被等待的boost::promise或者boost::packaged_task调用set_wait_callback()成员函数来实现。
这就是延迟期货:直到某线程需要结果的时候,才真正计算出结果。下面的例子中,f.get()调用回调函数invoke_lazy_task来运行任务,设置结果。如果移除f.get(),则任务不会运行。
4.8.4 期货参考
state枚举
unique_future模板类
shared_future模板类
promise模板类
packaged_task模板类
非成员函数wait_for_any()
n 前提条件:Fn类型应该是boost::unique_future或者boost::shared_future的特例,Iterator应该是value_type为boost::unique_future或者boost::shared_future的前向迭代器。
n 作用:等待至少一个指定的期货准备就绪。
n 返回:基于范围的重载形式返回一个迭代器,标识第一个被检测到准备就绪的期货。其他重载形式返回一个从零开始的索引,指示第一个被检测到准备就绪的期货。(第一个参数索引为0,第二个索引为1,等等)
n 异常:如果当前线程被中断,抛出boost::thread_interrupted;或者任何被等待期货的等待回调抛出的任何异常;如果内部等待结构不能分配内存,则抛出std::bad_alloc。
n 注意:wait_for_any()是一个中断点。
非成员函数wait_for_all()
n 前提条件:Fn类型应该是boost::unique_future或者boost::shared_future的特例,Iterator应该是value_type为boost::unique_future或者boost::shared_future的前向迭代器。
n 作用:等待所有期货准备就绪。
n 异常:对指定期货的wait()调用抛出的任何异常。
n 注意:wait_for_all()是一个中断点。
发表评论
-
2011年春季消费者行为分析1
2012-01-20 11:26 8232011年春季消费者行为分析1 2011年04月21日 ... -
高中英语语法复习――定语从句
2012-01-20 11:26 543高中英语语法复习――定语从句 2012年01月12日 更 ... -
初二期末测试题
2012-01-20 11:19 573初二期末测试题 17小时 ... -
【转】 接上pl0-分析
2012-01-19 16:06 743【转】 接上pl0-分析 2011年11月23日 (* ... -
Mapx 错误集合(转载)
2012-01-19 16:06 2275Mapx 错误集合(转载) 2011年10月04日 Th ... -
(推荐读)reading local files in javascript 在chrome中开发读取当地文本
2012-01-19 16:06 1678(推荐读)reading local files in jav ... -
Oracle异常处理
2012-01-19 16:06 609Oracle异常处理 2011年11 ... -
日少 サ妇
2012-01-17 05:57 455日少 サ妇 2011年11月04日 document.d ... -
女子被撞倒后拖行数百米致死 肇事车逼翻追赶者
2012-01-17 05:57 557女子被撞倒后拖行数百 ... -
河南周口警察将人打昏迷抛下楼致死 多人获刑
2012-01-17 05:57 667河南周口警察将人打昏迷抛下楼致死 多人获刑 2011年11月 ... -
2011-11-19-j
2012-01-17 05:57 5792011-11-19-j 2011年11月19日 ... -
别让印象骗了你、、、
2012-01-16 04:44 664别让印象骗了你、、、 2011年12月16日 “第一印象 ... -
二婚为何也能成为刘备皇后
2012-01-16 04:44 467二婚为何也能成为刘备 ... -
《诗经??国风??秦风》
2012-01-16 04:44 618《诗经??国风??秦风》 2011年12月21日 蒹 ... -
一代天骄成吉思汗的秘葬
2012-01-16 04:44 880一代天骄成吉思汗的秘 ... -
《论语》解读之3-19《使下以礼事上以忠》
2012-01-16 04:44 572《论语》解读之3-19《使下以礼事上以忠》 2011年12月 ...
相关推荐
通过boost::asio::serialport类实现串口通信的例子
详细讲述了boost::thread的用法
boost::lexical_cast用法示例,包含数值转字串,字串转数值以及相应的异常处理代码
boost::asio::serial下6个工程演示多种串口读取写入方式方法,包含simple,with_timeout,async,callback,qt_integration,stream 等多个工程演示多种方式读取,写入串口,char,string ,buffer[]等多种数据格式。
相信不少人听过 boost 委员会提过 boost 里的对象池设计存在缺陷。我花了一些时间研究它的实现,发现其在效率上确实存在严重问题。这里给出一套解决方案。在效率上有了较大提高。可以完全替换你项目里的 object_pool...
boost::asio完成了通讯模块的编写,界面用MFC简单做了一下。 局域网的测试结果: 传输速度在6-7m/s 并发到500,服务器CPU和网络应用均出现使用99%的情况出现硬件瓶颈,新连接无法建立(测试服务器比较差,CPU:...
此压缩包包含12个项目,每个项目都着重讲解Boost::Serialization一个方面的使用技巧,有详细的代码介绍具体使用方法。
(1)thread():构造一个表示当前执行线程的线程对象; (2)explicit thread(const boost::function0& threadfunc): boost::function0可以简单看为:一个无返回(返回void),无参数的函数。这里的函数也可以是类...
boost::asio库是一个支持异步I/O操作的网络编程库,它可以帮助开发者实现高性能、可扩展、多线程的网络应用程序。它基于事件驱动的模型,允许开发者同时处理多个连接和请求,并且不会阻塞主线程。boost::asio库还...
本文实例讲述了C++之boost::array的用法,分享给大家供大家参考。具体如下: 代码如下:#include #include #include <boost> #include using namespace std; int main() { boost::array<int> ...
主要介绍了C++ boost::asio编程-同步TCP详解及实例代码的相关资料,需要的朋友可以参考下
基于boost::asio的http server3修改的echo服务器,有多线程,多侦听端口,超时处理等
利用boost::asio 搭建一个C/S架构的服务端模型。 该服务端支持客户端长连接。 链接到其他服务器使用了链接池。
使用c++实现boost::any类 any类可以存放任意类型数据,如: void test_any() { any any_a1(123); int a2 = any_cast(any_a1); int* p_a2 = any_cast(&any_a1); std::cout *p_a2="*p_a2<<std::endl; any any_b1...
boost线程指南手册。Boost 1.35.0的中文版。
sqlite数据库,用c++封装类,以及源码实现的对sqlite数据库封装类的操作。同时有boost多线程对sqlite数据库进行操作。 真是学习居家的好例子。。。。
boost::any的C++实现 验证可用 有相关的问题欢迎讨论
使用VS2017编译的boost库最新版1.68的动态库和静态库,多线程参数,经过测试可用
boost 线程池源代码文档 2 sourceforge