代码之家  ›  专栏  ›  技术社区  ›  Steven Smethurst

标准::列出螺纹后推、前推、前推

  •  6
  • Steven Smethurst  · 技术社区  · 15 年前

    std::list线程安全吗?我假设不是这样,所以我添加了自己的同步机制(我认为我有正确的术语)。但我还是遇到了问题

    std::list<CFoo> g_buffer; 
    bool g_buffer_lock; 
    
    void thread1( CFoo frame ) {
        g_buffer_lock = true ; 
        g_buffer.push_back( frame ) ; 
        g_buffer_lock = false; 
    }
    
    
    void thread2( )
    {
        while( g_buffer_lock ) {
            // Wait 
        }
    
        // CMSTP_Send_Frame * pMSTPFrame = NULL ; 
        while ( ! g_buffer_lock && g_buffer.size() > 0 )
        {
            // Get the top item 
            CFoo& pFoo = g_buffer.front() ;
    
            // Do something. 
    
            // remove the front item 
            g_buffer.pop_front();
        }
    }
    

    在对thread1和thread2分别调用了170k和900k后,我在 CFoo& pFoo = g_buffer.front() ;

    #ifdef _DEBUG
    _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Debug_message(const wchar_t *message, const wchar_t *file, unsigned int line)
        {   // report error and die
            if(::_CrtDbgReportW(_CRT_ASSERT, file, line, NULL, message)==1)
            {
                ::_CrtDbgBreak();
            }
        }
    _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Debug_message(const unsigned short *message, const unsigned short *file, unsigned int line)
        {   // report error and die
            _Debug_message((wchar_t *) message, (wchar_t *) file, line);
        }
    
    #endif
    

    建议,评论,还有更好的方法吗?

    5 回复  |  直到 15 年前
        1
  •  15
  •   sbi    15 年前

    std::list线程安全吗?

    当前的C++标准甚至不承认线程的存在,所以 std::list 当然不是。但是,不同的实现可能提供(不同级别的)线程安全性。

    至于您的代码:如果您需要锁,请使用锁。那个 bool 当线程在从不同缓存获取它的不同内核上执行时,变量可能没有帮助。使用真正的互斥。

        2
  •  6
  •   Mehrdad Afshari    15 年前

    不,它不能保证线程安全。

    你的同步机制有缺陷。你允许 thread1 thread2 他正在与之合作。这可能会导致问题。除此之外,还应该使锁变为变量 volatile

        3
  •  1
  •   sdg    15 年前

    另外,您的同步机制可能不是很好。

    你的胸部,所以你有问题。

    你至少应该放一个 不稳定的 在你的锁门前的限定符;或者最好还是研究适合您的平台的真正互斥函数。

        4
  •  1
  •   Dima    15 年前

    编辑:

    事实上你可能会侥幸逃脱。。。Thread1仅向列表中添加元素,而Thread2仅删除元素。这意味着,只有当列表仅包含一个元素时,Thread1才需要等待。

    编辑2:

    因此,如果列表只包含一个元素,thread2可以锁定该列表。它必须在每次删除之前检查。这样一来,thread1就不必等待,除非发生了这样一种情况。

    而且您肯定应该使用适当的互斥机制(平台上的任何可用机制),而不是布尔标志。

        5
  •  0
  •   Caleb Huitt - cjhuitt    15 年前

    如果您确实需要thread1尽可能快,但仍然需要线程安全,则可以以最小的开销为代价防止一些锁争用,例如:

    std::list<CFoo> g_buffer_thread1;
    std::list<CFoo> g_buffer_thread2;
    Mutex g_mutex; 
    
    void thread1( CFoo frame ) {
        Locker lock( g_mutex );
        g_buffer_thread1.push_back( frame ) ; 
    }
    
    
    void thread2( )
    {
        while( g_buffer_thread2.size() == 0 ) {
            // Wait?
            Locker lock( g_mutex );
            g_buffer_thread1.swap( g_buffer_thread2 );
        }
    
        while ( g_buffer_thread2.size() > 0 )
        {
            CFoo& pFoo = g_buffer_thread2.front() ;
            // Do something.
            g_buffer_thread2.pop_front();
        }
    }
    

    我认为这是与线程安全性最直接的结合。不幸的是,Thread1必须始终锁定。您可能会想出一些方法,为thread1批处理帧。根据您在问题中的数字,我假设thread1的运行次数比thread2多得多,因此这将节省一些锁争用,否则仅使用一个缓冲区列表就会发生锁争用。