STL-----线程安全

由于STL不是线程安全的, 所以在每一次插入元素,删除元素,读取元素时,必须保证原子操作.
 读取元素也许要原子? 嗯,是的. 因为你得到了一个迭代器后, 这个迭代器对应的容器可能被别的线程修改!

所以(下面来自<<Effective STL>> 条款十二):
1)在每次调用容器的成员函数期间都要锁定该容器。
2)在每个容器返回的迭代器(例如通过调用begin或end)的生存期之内都要锁定该容器。
3)在每个在容器上调用的算法执行期间锁定该容器。(
这事实上没有意义,因为,正如条款32所解释的,算法没有办法识别出它们正在操作的容器。不过,我们将在这里检验这个选项,因为它的教育意义在于看看为什么即使是可能的它也不能工作。)


Multithreading Issues

STL is not thread protected, so you must provide locks on your collections if they will be used in multithreaded environment. The standard locking mechanisms of Mutexes, Semaphores and Critical Sections can be used. One simple mechanism for providing locking is to declare a lock class. In this class the constructor creates the lock, and the destructor destroys the lock. Then provide lock() and unlock() methods. For example:

class Lock
{
public:
	HANDLE    _hMutex;            // used to lock/unlock object
     
	Lock() : _hMutex(NULL)
	{ _hMutex = ::CreateMutex( NULL, false,NULL) ); }
     
	virtual ~Lock() { ::CloseHandle( _hMutex ); }
     
	bool lock ()
	{
		if ( _hMutex == NULL )
			return false;
		WaitForSingleObject( _hMutex, INFINITE );
		return true;
	}
     
	void unlock () { ReleaseMutex(_hMutex);      }
     
};

Then declare a class that is derived from one of the STL collections, and in the class override the access methods to the collection that might cause an insertion or deletion of an element. For example a general vector class would be:

template <class T>
class LockVector : vector<T>, Lock
{
public:
	LockVector () : vector<T>(), Lock()
	{}
	virtual LockVector ()
	{}
     
	void insert ( T & obj )
	{
		if ( !lock())
			return;
		vector<T>::push_back (obj);
		unlock();
	}
};
参考:http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2/blog/item/228c9d5c22cf9447faf2c0c6.html
条款12:对STL容器线程安全性的期待现实一些

标准C++的世界是相当保守和陈旧的。在这个纯洁的世界,所有可执行文件都是静态链接的。不存在内存映射文件和共享内存。没有窗口系统,没有网络,没有数据库,没有其他进程。在这种情况下,当发现标准没有提到任何关于线程的东西时你不该感到惊讶。你对STL的线程安全有的第一个想法应该是它将因实现而不同。

当然,多线程程序是很普遍的,所以大部分STL厂商努力使他们的实现在线程环境中可以正常工作。但是,即使他们做得很好,大部分负担仍在你肩上,而理解为什么会这样是很重要的。STL厂商只能为你做一些可以减少你多线程的痛苦的事情,你需要知道他们做了什么。

在STL容器(和大多数厂商的愿望)里对多线程支持的黄金规则已经由SGI定义,并且在它们的STL网站[21]上发布。大体上说,你能从实现里确定的最多是下列内容:

  • 多个读取者是安全的。多线程可能同时读取一个容器的内容,这将正确地执行。当然,在读取时不能有任何写入者操作这个容器。
  • 对不同容器的多个写入者是安全的。多线程可以同时写不同的容器。

就这些了,那么让我解释你可以期望的是什么,而不是你可以确定的。有些实现提供这些保证,但是有些不。

写多线程的代码很难,很多程序员希望STL实现是完全线程安全的。如果是那样,程序员可以不再需要自己做并行控制。毫无疑问这将带来很多方便,但这也非常难实现。一个库可能试图以下列方式实现这样完全线程安全的容器:

  • 在每次调用容器的成员函数期间都要锁定该容器。
  • 在每个容器返回的迭代器(例如通过调用begin或end)的生存期之内都要锁定该容器。
  • 在每个在容器上调用的算法执行期间锁定该容器。(这事实上没有意义,因为,正如条款32所解释的,算法没有办法识别出它们正在操作的容器。不过,我们将在这里检验这个选项,因为它的教育意义在于看看为什么即使是可能的它也不能工作。)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值