ostringstream to vector‹String› для многопоточной очереди

Итак, у меня есть приложение, представляющее собой сервер, который открывает несколько потоков, которые будут использоваться для запросов к базе данных. В моей функции приема я проверил вывод для своего запроса, который я построил, и он выглядит нормально, когда я вычисляю поток ostringstream, поэтому я добавляю его в вектор. Затем я вырезаю вектор, и он тоже выглядит нормально. Все это делается в блокировке мьютекса, поэтому я разблокирую мьютекс. Мои потоки базы данных находятся в цикле while, который проверяет, является ли мой vector.size() > 0.

Проблема, с которой я сталкиваюсь, заключается в том, что мой цикл никогда не запускается, потому что он никогда не видит вектор> 0 (что должно быть, потому что я смог вычислить вектор. начало (), и он работал нормально. Может ли кто-нибудь взглянуть на код У меня есть, и скажите мне, есть ли какие-либо проблемы, которые могут быть причиной этой проблемы.

#Header
class CNetworkService : public Service
{
   public:
CNetworkService(void);
~CNetworkService(void);
std::ostringstream query;
string  record;
std::vector<string> queue;
string IP;
unsigned int Port;
void DBWork();
bool SaveLog(string insert);
   protected:
virtual void handle(LogicalConnection* pClient, IncomingPacket* pRequest);
};

#Source File
//In my receive handler
    mtx.lock();
query << var1 << var2;

queue.push_back(query.str());
mtx.unlock();
query.clear();



//This is the function that the database threads are looping in
void CNetworkService::DBWork()
{


while(true)
{
mtx.lock();
while(queue.size() > 0)
{
    printf("Adding new record \n");
    SaveLog(queue.front());
    queue.erase(queue.begin());

}
mtx.unlock();
    }
    }

  //The code in the main thread which launches each thread. StartDBThread does some reporting stuff and then lauches the DBWork function, and I can see that DBWork is getting called. In the original attempt I was trying to launch 4 threads, but for now I have scaled it back to 1 thread in order to test and get a working solution.
  std::thread threads[1];
  // spawn 1 threads:
  for (int i=0; i<1; ++i)
  threads[i] = std::thread(StartDBThread, i+1);

  for (auto& th : threads) th.join();

person Uwop    schedule 22.04.2014    source источник
comment
Обычный способ использования потокобезопасных очередей — использование условных переменных. См. следующий пример: justsoftwaresolutions. co.uk/threading/   -  person stefaanv    schedule 22.04.2014
comment
Если вам действительно нужна очередь, почему бы не использовать std::queue?   -  person Some programmer dude    schedule 22.04.2014
comment
Спасибо, я не знал об очередях, но, к сожалению, этот вопрос не о векторах и очередях, и моя проблема все еще остается.   -  person Uwop    schedule 22.04.2014


Ответы (1)


Одна из возможных проблем, о которой я мог подумать, заключается в том, что мьютекс захватывается где-то еще в вашем коде, и CNetworkService::DBWork() так и не получил блокировку.

Это может быть не причиной проблемы. Но вы можете предотвратить это, задав для переменной mtx личное поле CNetworkService, поскольку оно используется для синхронизации очереди, и вы не хотите, чтобы оно использовалось где-либо еще.

Я предлагаю вам проверить, напечатав что-то между mtx.lock() и while(queue.size() > 0), чтобы увидеть, будет ли когда-либо получена блокировка.

P.S. vector::erase очень дорого.

person Yifu Wang    schedule 22.04.2014
comment
Я могу получить блокировку в другом потоке, проблема в том, что другой поток никогда не видит, что размер моего вектора увеличивается. Я только что попытался вывести первое значение моего вектора, используя cout ‹‹ queue.front() ‹‹ endl; и я не могу в потоке DBWork, в блокировке мьютекса. - person Uwop; 22.04.2014
comment
Также спасибо за подсказку о векторном стирании, я изменил его на pop_back() - person Uwop; 22.04.2014
comment
@ AES256 Вы хотите убедиться, что поток, вызывающий CNetworkService::DBWork(), не видит увеличения размера или условие queue.size() > 0 вообще никогда не выполняется. Похоже на второй случай, это, вероятно, означает, что mtx захвачен каким-то другим потоком и не освобождается. Кроме того, вы присоединились к потоку, который вызывает CNetworkService::DBWork() в вашем основном потоке? Было бы полезно, если бы вы вставили код. - person Yifu Wang; 22.04.2014
comment
Вот код создания потока. std::thread threads[1]; // создать 1 поток: for (int i=0; i‹1; ++i) threads[i] = std::thread(StartDBThread, i+1); for (auto& th : threads) th.join(); - person Uwop; 23.04.2014
comment
Я также добавил его в основной пост в нижней части раздела кода. - person Uwop; 23.04.2014