对C++中的队列进行多线程访问
Multi-threaded access to a Queue in C++
所以基本上我有两个线程:一个生成字符串的组合并将它们附加到作为类成员的队列中。 第二个线程应该将该队列中的所有内容打印到文件中。如果队列为空,我应该等到有另一个元素,依此类推。
std::mutex m;
Class c{
std::queue<std::string> q;
std::ofstream file;
void print(std::string str){
file << str << "n";
} // Print to file
void generate(){
str = "abc" // do stuff
q.push(str);
}
}
当我使用std::mutex
程序的性能变得非常糟糕时。 我想我需要一个管理对队列的访问的函数,以便我可以同时写入和打印。我该怎么做?
void Generator::print() {
int c = 0;
while (c < totalN){
if(!printQueue.empty()){
fileStream << printQueue.front() << 'n';
printQueue.pop();
c++;
}
}
}
void Generator::getCombinations(unsigned long start, unsigned long end) {
// Fill with dummy elements
std::string comb(length, ' ');
std::string temp(length, ' ');
auto total_n = static_cast<unsigned long>(std::pow(elementCount, length));
for (auto i = start; i < end; ++i) {
auto n = i;
for (size_t j = 0; j < length; ++j) {
comb[comb.size() - j - 1] = charPool[n % elementCount];
n /= elementCount;
}
temp = comb;
for (auto f : tasks) (this->*f)(temp); // Call addQueue func
}
}
void Generator::addToQueue(std::string &str) {
m.lock();
printQueue.push(str);
m.unlock();
}
出于某种原因,我收到错误的访问错误,因为 prints 函数尝试从空队列中打印某些内容,这对我来说似乎是不可能的,因为这部分代码仅在队列不为空时才执行......
在Generator::Print
函数中,最好将共享队列换成空队列,然后使用内容:
void Generator::print() {
int todo = totalN;
while (todo) {
std::this_thread::sleep_for(500ms);
std::queue<std::string> temp;
{ // Lock only taken for this section
std::lock_guard<std::mutex> lock(m);
std::swap(temp, q);
}
todo -= temp.size();
while (!temp.empty()) {
fileStream << temp.front() << 'n';
temp.pop();
}
}
}
这最多每 500 毫秒锁定一次,并且仅足够长的时间将q
替换为temp
。然后它可以按照自己的节奏打印内容。
请注意,如果生成比打印慢得多,您可以一次弹出一个,而不是像我在这里所做的那样交换队列。
这是一个称为生产者/消费者队列的标准问题。
C++ 中,当前开箱即用的解决方案是 condition_variable。如果您点击该链接,您将找到一个示例解决方案。注意您缺少的一些功能
- 始终通过标准::lock_guard或标准::unique_lock锁定/解锁。
- 如果速度很重要,请使用条件变量来控制每个线程唤醒或睡眠的时间。
- 对结构的每个访问都必须同步。这包括推送/弹出,甚至包括调用清空等常量函数。
给定你的代码在哪里,并且考虑到问题是众所周知的。我建议你应该开始寻找现有的代码。从扫描中读取,这看起来像一个合理的概述。特别是,查看"有界缓冲区"部分。
Boost有一些不使用互斥锁的实现。这比您似乎需要的更先进。我不会为你建议这个,但其他人可能会觉得这很有趣。 https://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/queue.html
相关文章:
- 对C++中的队列进行多线程访问
- 对全局变量的多线程访问:我应该使用互斥锁吗?
- cuda:多个线程访问同一个全局变量
- 多线程可以访问同一weak_ptr对象C++吗?
- 多个线程访问同一个 cuda 流
- 多线程环境中C++内存访问
- 从多个线程访问类对象
- 多个线程访问共享资源
- 从多个线程访问 QTcpSocket
- std::d eque 和多线程访问
- 共享内存多线程和数据访问
- 如何使用QT/C 中的多线程用API访问我的数据库
- C++ 从多个线程访问矢量
- 控制对多线程程序中字符串对象的访问的最佳方法
- CUDA 多线程:__threadfence不会阻止多个线程访问资源
- 堆HEAP_NO_SERIALIZE中的多线程访问
- 对unordered_map进行多线程访问的运行时错误
- 如何为多线程访问实现类锁定对象
- TBB concurrent_bounded_queue多线程访问
- 需要帮助模板化多线程访问的结构