我发布了上一个问题"Seg Fault when using std::string on an embedded Linux platform",我得到了一些非常有用的建议。从那时起我就离开了其他项目,并且最近回到了这个问题。
重申一下,我只能使用arm-linux交叉编译器(版本2.95.2),因为这是嵌入式平台供应商提供和支持的。我理解这个问题可能是因为stdlib非常老,而且特别是线程安全。
问题是每当我在多个线程中使用STL容器时,我最终都会出现分段错误。除非我在容器声明周围使用pthread_mutex_lock和范围运算符(如在其他帖子中一样),否则下面的代码将一直是错误的。
在我的应用程序中使用此方法是不可行的,因为我将容器传递给不同的方法和类。我理想地想解决这个问题,或者找一个合适的替代方案。我尝试过STLPort和SGI的标准模板库,结果相同。我只能假设因为它们是由非常古老的gcc链接的,所以它们无法解决问题。
有没有人有任何可能的建议或解决方案?或者你可以建议我可以放入我的代码中的vector(和string)的实现吗?
提前感谢任何指导。
#include <stdio.h>
#include <vector>
#include <list>
#include <string>
using namespace std;
/////////////////////////////////////////////////////////////////////////////
class TestSeg
{
static pthread_mutex_t _logLock;
public:
TestSeg()
{
}
~TestSeg()
{
}
static void* TestThread( void *arg )
{
int i = 0;
while ( i++ < 10000 )
{
printf( "%d\n", i );
WriteBad( "Function" );
}
pthread_exit( NULL );
}
static void WriteBad( const char* sFunction )
{
//pthread_mutex_lock( &_logLock );
//{
printf( "%s\n", sFunction );
string sKiller; // <----------------------------------Bad
//list<char> killer; // <----------------------------------Bad
//vector<char> killer; // <----------------------------------Bad
//}
//pthread_mutex_unlock( &_logLock );
return;
}
void RunTest()
{
int threads = 100;
pthread_t _rx_thread[threads];
for ( int i = 0 ; i < threads ; i++ )
{
pthread_create( &_rx_thread[i], NULL, TestThread, NULL );
}
for ( int i = 0 ; i < threads ; i++ )
{
pthread_join( _rx_thread[i], NULL );
}
}
};
pthread_mutex_t TestSeg::_logLock = PTHREAD_MUTEX_INITIALIZER;
int main( int argc, char *argv[] )
{
TestSeg seg;
seg.RunTest();
pthread_exit( NULL );
}
答案 0 :(得分:6)
问题不在于容器,而在于您的代码。
完全没必要让容器本身是线程安全的,因为你首先需要的是类似事务的语义。
为了演示,我们假设你有一个vector
的线程安全实现。
if (!vec.empty())
vec.clear();
foo = vec.front();
这会导致未定义的行为。
问题在于,对容器线程安全进行每个操作都是毫无意义的,因为您仍然需要能够连续锁定容器本身以进行多个操作。因此,您会锁定各种操作,然后再次锁定每个操作?
正如我所说:完全没必要。
答案 1 :(得分:2)
您的部分查询可能会在another thread中得到解答。 C ++的设计,包括标准库,受到许多因素的影响。效率是一个重复的主题。线程安全机制通常与效率目标不一致。图书馆的时代并不是真正的问题。
根据您的情况,您可以将STL向量包装在您自己的向量类中(您可能会考虑Decorator),其中包含锁定机制并提供围绕访问的锁定/解锁逻辑。