线程安全的向量和字符串容器?

Bra*_*rad 2 c++ linux arm stl segmentation-fault

我发布了一个上一个问题"在嵌入式Linux平台上使用std :: string时出现Seg Fault",我得到了一些非常有用的建议.从那以后我就离开了其他项目,最近又回到了这个问题.

重申一下,我只能使用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 );
    }
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 6

问题不在于容器,而在于您的代码.

完全没有必要使容器本身是线程安全的,因为首先需要的是类似事务的语义.

例如,为了演示,我们假设你有一个线程安全的实现vector.

  • 线程1: if (!vec.empty())
  • 线程2: vec.clear();
  • 线程1: foo = vec.front();

这导致未定义的行为.

问题是在容器线程安全上进行每个操作都是毫无意义的,因为您仍然需要能够连续锁定容器本身以进行多个操作.因此,您会锁定各种操作,然后再次锁定每个操作?

正如我所说:完全没必要.

  • Matthieu,我完全理解你所说的并理解在线程之间共享容器实例时会有未定义的行为.但是我遇到的问题是本地堆栈实例正在踩着彼此的脚趾.为什么我需要锁定局部变量? (2认同)