2013-04-19 2 views
0

Я использую map<int, queue<string>>, где int ссылается на источник сообщения, а queue содержит сообщение. Один поток помещает сообщения в очередь, другой поток выталкивает их из очереди.карты очередей очередей: используя [] vs .insert

Это клиент-серверная программа - когда клиент отправляет сообщение, сообщение попадает в очередь.

настоящее время я использую (псевдокод)

/*receive message in thread 1*/ 
map<int, queue<string>> test_map; 
int client_id = 2; 
string msg = received_from_client(client_id); 
testmap[client_id].push(msg); 

/*process message in thread 2*/ 
string msg_to_process testmap[client_id].front(); 
test_map[client_id].pop(); 

if (testmap[client_id].empty()) 
{ 
    testmap.erase(client_id); 
} 

Я знаю, что из этого question, что разница в том, что вставка не будет перезаписывать существующий ключ - это применить, когда я толкая вещи в очередях? Безопаснее ли использовать вставку, или это то, что я делаю с []?

Также - в то время как система должна только одно сообщение в очереди в любое время, я делаю пособие расширения с помощью map<int, queue> вместо использования map<int,string>.

редактировать: У меня есть вопрос о множественной резьбе, а также - что происходит, когда нить 1 попытку вставить карту в то время как поток 2 удаляет ключ, потому что очередь пуста (после того, как он обработал сообщение). Является ли это количественным ответом на это, и использует ли [] или insert() помочь сделать его более поточным?

+0

В дополнение к тому, что может возникнуть в связи с некоторыми интересными проблемами параллелизма, когда вы вводите в него потоковую обработку, управление использованием 'operator []' для индексирования очереди идентификатора клиента для вставки, переднего и поп-шаблона выглядит корректно здесь , Вы можете использовать интеллектуальные указатели для своего значения карты, если вы планируете использовать это в многопоточной среде (по причинам, которые вы обнаружите, когда вы туда попадете). – WhozCraig

+0

Я на самом деле задаю этот вопрос, потому что программа иногда ломается - все еще проверяя причину - у меня есть другой вопрос о вставке и удалении - я отредактирую вопрос! – sccs

+0

. Тогда возникает вопрос, как этот код разбивается на многопоточную среду? (происходит ли первоначальная невысказанная, недокументированная и, следовательно, неизвестная ошибка в однопоточном контексте)? – WhozCraig

ответ

0

У Queue нет ключей или [] операторов, поэтому на ваш первый вопрос нельзя ответить. Вы вставляете в очередь, нажимая на спину. Если там есть элементы, они будут идти за ними. Вы читаете очередь, выбирая вещи спереди, если они есть. Вы не читаете и не пишете нигде, кроме этого.

Что касается карт, как вы сказали, вставка добавит новую пару ключ-значение, если она еще не существует. Он не перезапишет существующий ключ. Find найдет значение, если оно уже существует, но не будет вставлять его, если это не так. И тогда оператор [] выполняет оба действия, а также позволяет изменять существующие элементы. Документация here очень хорошая.

Одна вещь, о которой следует знать, заключается в том, что использование оператора карты [] для чтения с карты также будет включать в себя элемент valueetype по умолчанию с этой клавишей и, вероятно, не так, как вы ожидали бы при первом взгляде на него ,

std::map<int, int> myMap; 
if(myMap[1] == 0) //[] create's a key-value pair <1,0> 
    cout << "This will output"; 
if(myMap.size() == 1) 
    cout << "This too"; 

Что касается аспекта безопасности нитей, то STL-контейнеры не являются потокобезопасными на основе стандарта. Вам нужно добавить правильную блокировку в свой код, чтобы точно не спросить о том, о чем вы просили. Если два потока попытались одновременно прочитать и записать из очереди, это почти наверняка вызовет ошибку. Я бы пообщался о написании программ, защищенных потоками, для общей помощи о том, как это сделать.

+0

Спасибо - мой вопрос всегда касался '[]' и 'insert' wrt к картам (это была опечатка с моей стороны, извините). Что касается этого, вставляя элемент valuetype по умолчанию - каково его решение? Использовать 'find() -> second'? – sccs

+0

есть. если вы хотите что-то искать, не вставляя значение по умолчанию, вам нужно использовать find, который вернет итератор в std :: pair , так что вы можете вызывать -> второй для этого, чтобы получить значение. вам нужно убедиться, что итератор не равен mymap.end(), прежде чем использовать его, хотя, так как это говорит о том, что ключ не найден. Есть хорошие объяснения и примеры [здесь] (http://www.cplusplus.com/reference/map/map/find/) – bdwain

+0

, поэтому в вашем примере, если вы искали очередь с идентификатором 7, и не было, пустая очередь будет создана и помещена на карту. – bdwain

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