【问题标题】:ostringstream to vector<String> for Multithreaded Queueostringstream 到 vector<String> 用于多线程队列
【发布时间】:2014-06-06 23:05:09
【问题描述】:

所以我有一个应用程序,它是一个打开多个线程的服务器,这些线程将用于数据库查询。在我的接收函数中,我测试了我构建的查询的输出,当我计算出 ostringstream 时它看起来很好,所以我将它添加到向量中。然后我 cout 向量,它看起来也很好。这一切都是在互斥锁内完成的,所以我解锁了互斥锁。我的数据库线程处于一个 while 循环中,它检查我的 vector.size() 是否 > 0。

我遇到的问题是我的循环永远不会运行,因为它永远不会看到向量 > 0(应该是因为我能够计算 vector.begin() 并且它工作正常。有人可以看看在我拥有的代码中并告诉我是否有任何问题可能导致此问题。

#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();

【问题讨论】:

  • 使用线程安全队列的常规方法是使用条件变量。请参见以下示例:justsoftwaresolutions.co.uk/threading/…
  • 如果你真的想要一个队列,为什么不使用std::queue
  • 谢谢,我不知道队列,但不幸的是,这个问题与向量与队列无关,我的问题仍然存在。

标签: c++ multithreading vector standard-library


【解决方案1】:

我能想到的一个可能的问题是,在您的代码中的其他地方获取了互斥锁,而CNetworkService::DBWork() 从未获得过锁。

这可能不是问题的原因。但是您可以通过将 mtx 变量设置为 CNetworkService 的私​​有字段来防止它,因为它用于同步队列并且您不希望它在其他地方使用。

我建议您通过在 mtx.lock()while(queue.size() &gt; 0) 之间打印一些内容来进行测试,以查看是否曾经获得过锁。

附: vector::erase 很贵。

【讨论】:

  • 我能够在另一个线程中获得锁,问题是另一个线程永远不会看到我的向量的大小在增加。我刚刚尝试使用 cout
  • 另外感谢有关矢量擦除的提示,我将其更改为 pop_back()
  • @AES256 您想确保调用CNetworkService::DBWork() 的线程没有看到大小增加,或者queue.size() &gt; 0 条件根本不会被执行。听起来像第二种情况,这可能意味着mtx 正在被其他线程获取并且没有被释放。另外,您是否在主线程中加入了调用CNetworkService::DBWork() 的线程?如果您粘贴代码会很有帮助。
  • 这里是线程创建代码。 std::thread 线程[1]; // 产生 1 个线程: for (int i=0; i
  • 我也将它添加到代码部分底部的主帖中。
猜你喜欢
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
相关资源
最近更新 更多