2017-11-16 9 views
-1

2つのスレッドが同時にSTLベクトル用にメモリを割り当てようとすると、マルチスレッド実行シナリオで、従来のC++コードベースが失敗しています。 2つのスレッドのスタックトレースを以下に示します。スタックトレースからC++ STLアロケータ関数をオーバーライドしてスレッドセーフとしてラベリングする

----------------- lwp# 4/thread# 4 -------------------- 
00136e10 allocate__t24__default_alloc_template2b0i0Ui (4, 4, 0, 0, 0, 0) + a4 
0015ee80 allocate__t12simple_alloc2ZP12ReconInitRecZt24__default_alloc_template2b0i0Ui (1, 0, 0, 0 
, 0, 0) + 20 
0015da24 _M_allocate__t18_Vector_alloc_base3ZP12ReconInitRecZt9allocator1ZP12ReconInitRecb1Ui (86f 
204, 1, 0, 0, 0, 0) + 10 
0014f438 _M_insert_aux__t6vector2ZP12ReconInitRecZt9allocator1ZP12ReconInitRecPP12ReconInitRecRCP1 
2ReconInitRec (86f204, 0, fbe7fd04, 0, 0, 0) + cc 
0015f0a8 push_back__t6vector2ZP12ReconInitRecZt9allocator1ZP12ReconInitRecRCP12ReconInitRec (86f20 
4, fbe7fd04, 0, 0, 0, 0) + 5c 
0015dbc0 push_back__t26ReconListOfRecFromMMapFile1ZP12ReconInitRecRCP12ReconInitRec (86f1f0, fbe7f 
d04, 0, 0, fc551200, ff120400) + 28 
0017ca48 preprocess__8ReconCmpRCt26ReconListOfRecFromMMapFile1ZP12ReconInitRecb (86f160, 975100, 0 
, b4, b4, 1) + 268 
<<other stacktrace details truncated>>  
. . . . 
ff1494f0 _lwp_start (0, 0, 0, 0, 0, 0) 
----------------- lwp# 5/thread# 5 -------------------- 
ff14d1e4 _lwp_kill (6, 0, ff1b5010, ff12c928, ffffffff, 6) + 8 
ff0c1bac abort (1f2b24, 1, 264ae4, ee930, ff1b34d8, 0) + 110 
001f2ca8 corehandler__7CdrSigsi (a, 0, fbaff4a8, 1, fedb2c40, cb4) + 184 
ff14961c __sighndlr (a, 0, fbaff4a8, 1f2b24, 0, 1) + c 
ff13dce8 call_user_handler (a, 0, 4, 0, fc551a00, fbaff4a8) + 3b8 
ff13ded0 sigacthandler (a, 0, fbaff4a8, 0, 0, 0) + 60 
--- called from signal handler with signal 10 (SIGBUS) --- 
00136e10 allocate__t24__default_alloc_template2b0i0Ui (8, 8, fbaffa38, 2d, 0, 0) + a4 
00126300 allocate__t12simple_alloc2Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc 
_template2b0i0Zt24__default_alloc_template2b0i0Ui (2, 4, ffffffff, fbaffa38, 2d, 80808080) + 20 
00126338 _M_allocate__t18_Vector_alloc_base3Zt12basic_string3ZcZt18string_char_traits1ZcZt24__defa 
ult_alloc_template2b0i0Zt9allocator1Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc 
_template2b0i0b1Ui (86f2a0, 2, 2d, fbaffa65, fbaffa65, 1) + 10 
00133768 _M_insert_aux__t6vector2Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_t 
emplate2b0i0Zt9allocator1Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b 
0i0Pt12basic_string3ZcZt18string_char_traits1ZcZt24__defa (86f2a0, 8730b4, fbaffa20, fcbf4062, fbaf 
fa65, 7fffffd2) + fc 
00157808 push_back__t6vector2Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_templ 
ate2b0i0Zt9allocator1Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0R 
Ct12basic_string3ZcZt18string_char_traits1ZcZt24__default (86f2a0, fbaffa20, 7ffffc00, fcbf4062, 1c 
, 2d) + 5c 
002064b8 getFiles__7ListDirb (86f280, 0, 253800, 4, 1c00, 1d3c) + 12c 
<<other stacktrace details truncated>>  
. . . . 

、これはスレッドセーフではないようallocate__t24__default_alloc_template2b0i0Uiへの同時呼び出し、すなわち__default_alloc_template<false, 0>::allocate(unsigned int)が失敗していることを示しています。 この割り当て機能は、私はこれらの三つの機能の1を上書きしたい順番に

_Vector_alloc_base<X, allocator<X>, true>::_M_allocate 
(unsigned int) 

によって呼び出され

simple_alloc<X, __default_alloc_template<false, 0> >::allocate(unsi 
gned int) 

という関数によって呼び出されている、FPRオーバーライドC++ STLアロケータ機能は、それをラップします相互排他保証の下でスレッドセーフとして保護されます。 お知らせください。

+4

通常malloc/newはスレッドセーフです。 (小さな組み込みシステムではルールに例外があるかもしれません) コンテナをスレッドセーフな方法で使用するかどうかを確認してください – Alexander

+0

BTW両方のスレッドから同じベクトルにアクセスしますか? – Alexander

+4

あなたは並行性のバグがあります。アロケータの回避策はそれを修正するものではありません。 – molbdnilo

答えて

1

コンテナのスレッドを安全にする代わりに、コンテナへのアクセスを同期する必要があります。あなたが車輪を再発明しようとすると、それは悪夢に終わるでしょう。挿入と削除の操作だけでなく、要素のコピーとシフト、および格納された要素に対する同時操作もあります。

実際には、あなたのデザインが壊れていると思います。コンテナのアロケータはアプリケーションに設計上の欠陥があることを示しています。ところで

:たぶんあなたの代わりに車輪の再発明を、すでに実装スレッドセーフなコンテナを使用することができます。

http://libcds.sourceforge.net/

http://www.boost.org/doc/libs/1_55_0/doc/html/lockfree.html

備考:私はそれらを使ったことがないと堅牢性については何も言うことができませんか、その他の品質問題

関連する問題