2013-02-13 4 views
0

Я проектирую tcp-сервер, который берет информацию из запроса и помещает все в очередь для обработки. Я использую веб-сервер asio для обработки всего веб-взаимодействия. Я ищу эффективный способ поставить все в очередь на процессы. Я использую сигналы форсирования и глобальный вектор, чтобы сделать это прямо сейчас, похоже на это.Связь между потоками через общий вектор

void request_handler::handle_request(request &req, reply &rep) 
{ 
    std::string parsedInfo = parse_request(req); 
    shared_queue.push_back(parsedInfo); 
    new_entry(); 
} 

new_entry является повышение сигнала

boost::signal<void()> new_entry; 

Прямо сейчас у меня есть класс-обработчик сигнала, чтобы поймать сигнал.

void sig_handler::process_next() 
{ 
    boost::try_mutex::scoped_try_lock lock(guard); 
    if(!lock) 
     return; 
    while(!shared_queue.empty()) 
    { 
     ... //Do Stuff 
     std::string cur_entry = shared_queue.at(0); 
     shared_queue.erase(shared_queue.begin()); 
     ... //Do more stuff 
    } 
} 

Моя цель - очистить векторную очередь, когда в ней есть информация, и каждый раз что-то нажимается на вектор. Я хотел бы избежать опроса как можно больше. Я считаю, что эта часть работает так, как я ожидаю. Тем не менее, я получаю случайный крах из-за того, что, на мой взгляд, основано на моей обратной стороне, толкает информацию об общей очереди. Это происходит только тогда, когда я пытаюсь сделать 1000 транзакций в секунду, что затрудняет отладку в многопоточной среде. Моя спина след здесь:

Error: signal 11: 
./UpdateServer/build/UpdateServer(_Z7handleri+0x18)[0x469f68] 
/lib/x86_64-linux-gnu/libc.so.6(+0x364a0)[0x7fbbdd67a4a0] 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSsC1ERKSs+0xb)[0x7fbbddfb4f2b] 
./UpdateServer/build/UpdateServer[0x4749d0] 
./UpdateServer/build/UpdateServer(_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs+0x111)[0x476521] 
./UpdateServer/build/UpdateServer(_ZN15request_handler14handle_requestERK7requestR5reply+0x3d3)[0x475873] 
./UpdateServer/build/UpdateServer(_ZN10connection11handle_readERKN5boost6system10error_codeEm+0x234)[0x46c774] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail14strand_service8dispatchINS1_7binder2INS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS5_5list3INS5_5valueINS_10shared_ptrIS9_EEEEPFNS_3argILi1EEEvEPFNSK_ILi2EEEvEEEEESB_mEEEEvRPNS2_11strand_implET_+0xcd)[0x47216d] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS5_5list3INS5_5valueINS_10shared_ptrIS9_EEEEPFNS_3argILi1EEEvEPFNSK_ILi2EEEvEEEEEEclISB_mEEvRKT_RKT0_+0xd9)[0x472439] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail18completion_handlerINS1_17rewrapped_handlerINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS8_5list3INS8_5valueINS_10shared_ptrISC_EEEEPFNS_3argILi1EEEvEPFNSN_ILi2EEEvEEEEEEESE_mEESV_EEE11do_completeEPNS1_15task_io_serviceEPNS1_25task_io_service_operationESG_m+0x1e5)[0x4726f5] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail14strand_service8dispatchINS1_17rewrapped_handlerINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS9_5list3INS9_5valueINS_10shared_ptrISD_EEEEPFNS_3argILi1EEEvEPFNSO_ILi2EEEvEEEEEEESF_mEESW_EEEEvRPNS2_11strand_implET_+0x2ad)[0x472aed] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail19asio_handler_invokeINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS7_5list3INS7_5valueINS_10shared_ptrISB_EEEEPFNS_3argILi1EEEvEPFNSM_ILi2EEEvEEEEEEESD_mEES6_SU_EEvRT_PNS4_IT0_T1_EE+0x15f)[0x472d3f] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail23reactive_socket_recv_opINS0_17mutable_buffers_1ENS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS7_5list3INS7_5valueINS_10shared_ptrISB_EEEEPFNS_3argILi1EEEvEPFNSM_ILi2EEEvEEEEEEEE11do_completeEPNS1_15task_io_serviceEPNS1_25task_io_service_operationESF_m+0xce)[0x472ede] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail15task_io_service3runERNS_6system10error_codeE+0x79a)[0x47ceea] 
./UpdateServer/build/UpdateServer(_ZN5boost4asio10io_service3runEv+0x25)[0x47d1d5] 
/usr/lib/libboost_thread.so.1.48.0(+0xdda9)[0x7fbbdecd4da9] 
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a)[0x7fbbdd42ee9a] 
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fbbdd737cbd] 

Линия ./UpdateServer/build/UpdateServer(_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs+0x111)[0x476521]

кажется, demangle к StD :: вектор вставки итератор, поэтому я полагаю, что моя программа врезаться на общем вектор вставки (я не верю У меня есть другие векторы строк в моей программе), однако я достаточно уверен, что я использую свой вектор безопасным способом, как для вставки, так и для чтения.

Так что, я думаю, мой вопрос в том, когда я нажимаю информацию на общий вектор, есть ли проблемы с условиями гонки, которые я должен беспокоиться о том, что может привести к моему краху? И подход, который я принимаю по приемлемым подходам, или мне нужно каким-то образом пересмотреть мой дизайн? Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, я буду рад предоставить все, что смогу.

Спасибо

+0

Является 'shared_queue' типа' vector '? – JaredC

+0

Opps, извините, что, да. И общая очередь в request_handler и sig_handler - это один и тот же объект. – Eumcoz

ответ

2

std структура данных не являются поточно (for the most part) и, следовательно, требует дополнительной синхронизации, если доступ нескольких потоков одновременно. В вашем случае один поток может вызывать push_back, а другой поток вызывает erase. Это приведет к возникновению неопределенного поведения. Чтобы исправить это, необходимо, чтобы и push_back, и erase были защищены одним и тем же замком. Я рекомендую вам google для обеспечения безопасности потоков в стандартной библиотеке C++ и узнать больше об этом.


Кроме того, использование vector здесь, вероятно, не самый лучший выбор. Вместо этого вы должны посмотреть на std::queue. Когда вы erase, первый элемент vector должен скопировать все строки позже в вектор вниз, что может быть очень дорого. queue не страдает этой проблемой.

+0

Спасибо, я обязательно дам этот снимок, кажется, что это, вероятно, решение, и хорошо знать о очередях, я тоже переключу свой вектор. – Eumcoz

+0

std :: deque ............ –

+0

Похоже, что это сработало, большое вам спасибо. – Eumcoz

Смежные вопросы