2017-11-16 10 views
-1

두 스레드가 동시에 STL 벡터에 메모리를 할당하려고 시도하면 다중 스레드 실행 시나리오에서 기존 C++ 코드베이스가 실패합니다. 두 스레드의 스택 추적이 아래에 나와 있습니다. 스택 트레이스에서 C++ STL 할당 자 함수를 스레드 세이프 (threadafe)로 랩핑하는 방법을 재정의합니다.

----------------- 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) 동시 호출이 실패한 것을 나타낸다. 이 할당 기능이 나는이 세 가지 기능 중 하나를 덮어 쓰려 차례로

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

에 의해 불려

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

하는 기능에 의해 호출되고, FPR 오버라이드 (override) C++ STL 할당 기능을 포장하기 상호 배타 보장하에 스레드 세이프로 보호됩니다. 알려주십시오.

+4

일반적으로 malloc/new는 스레드로부터 안전합니다. (작은 임베디드 시스템에서 규칙에 예외가있을 수 있음) 컨테이너를 스레드 안전 방식으로 사용하는지 확인하십시오 – Alexander

+0

BTW 두 스레드에서 동일한 벡터에 액세스합니까? – Alexander

+4

동시성 버그가 있습니다. 할당 자 해결 방법의 양은 그것을 고칠 수 없습니다. – molbdnilo

답변

1

용기를 안전하게 만드는 대신 컨테이너에 대한 액세스를 동기화해야합니다! 당신이 바퀴를 재발 명하려고한다면 그것은 악몽에 빠지게 될 것입니다. 삽입 및 제거 작업뿐만 아니라 요소 복사 및 이동 및 저장된 요소에 대한 동시 작업도 있습니다.

사실, 귀하의 설계가 깨졌으며 컨테이너 할당자는 응용 프로그램에 설계 결함이 있음을 보여줄뿐입니다.

BTW : 어쩌면 당신은 이미 대신 바퀴를 개혁의 스레드 안전 컨테이너를 구현 사용할 수 있습니다

http://libcds.sourceforge.net/

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

비고 : 내가 그들을 사용한 적이과 견고성에 대해 아무것도 말할 수 없다거나 다른 품질 문제.