- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于大数组(10^7 个元素)上的信号处理,我使用与环形缓冲区连接的不同线程。遗憾的是,将数据复制到缓冲区或从缓冲区复制出数据就需要太多时间。当前的实现基于 boost::lockfree::spsc_queue
。
因此,我正在寻找一种解决方案,通过对 vector 使用 unique_ptr 在线程和缓冲区之间交换 vector 的所有权(请参阅附图: swapping pointer between threads and the queue )。
move 智能指针不符合我的需求,因为因此我需要在运行时不断为新的 vector 元素分配内存。该开销比复制数据更大。
我是否遗漏了该设计中的缺陷?
是否有线程安全甚至无锁的环形缓冲区实现允许推送和弹出交换操作?
编辑:我修改了一个锁定环缓冲区来交换unique_ptr
。性能提升是巨大的。尽管它感觉不是一个优雅的解决方案。有什么建议吗?
// https://github.com/embeddedartistry/embedded-resources/blob/master/examples/cpp/circular_buffer.cpp
#include <memory>
#include <mutex>
template <typename T, int SIZE>
class RingbufferPointer {
typedef std::unique_ptr<T> TPointer;
public:
explicit RingbufferPointer() {
// create objects
for (int i=0; i<SIZE; i++) {
buf_[i] = std::make_unique<T>();
}
}
bool push(TPointer &item) {
std::lock_guard<std::mutex> lock(mutex_);
if (full())
return false;
std::swap(buf_[head_], item);
if (full_)
tail_ = (tail_ + 1) % max_size_;
head_ = (head_ + 1) % max_size_;
full_ = head_ == tail_;
return true;
}
bool pop(TPointer &item) {
std::lock_guard<std::mutex> lock(mutex_);
if (empty())
return false;
std::swap(buf_[tail_], item);
full_ = false;
tail_ = (tail_ + 1) % max_size_;
return true;
}
void reset() {
std::lock_guard<std::mutex> lock(mutex_);
head_ = tail_;
full_ = false;
}
bool empty() const {
return (!full_ && (head_ == tail_));
}
bool full() const {
return full_;
}
int capacity() const {
return max_size_;
}
int size() const {
int size = max_size_;
if(!full_) {
if(head_ >= tail_)
size = head_ - tail_;
else
size = max_size_ + head_ - tail_;
}
return size;
}
private:
TPointer buf_[SIZE];
std::mutex mutex_;
int head_ = 0;
int tail_ = 0;
const int max_size_ = SIZE;
bool full_ = 0;
};
最佳答案
Moving smart pointers doesn't fit my needs, because therefore I need to allocate memory during runtime constantly for new vector elements.
如果您预先分配足够的存储并实现自己的内存管理(简单的隔离存储,又名池),则不一定正确。
如果你这样做,就没有什么可以阻止你进行交换,并且你可以使用任何支持元素交换的环缓冲区来保持现有的架构,并保持与你拥有的相同的线程安全性前。您可以仅勾选 using boost::pool
选项而不是实现您自己的。
关于c++ - 用于大数组的无复制线程安全环形缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52201212/
我正在尝试从网站(名称)“抓取”一些数据。我知道如何获得列表中的第一个名字——但我需要以同样的方式保存几千个名字。 这是我的代码: library(rvest) library(tidyverse)
我正在尝试制作一个环形 UIBezierPath 用作 CAShapeLayer 的 path 以下产生一个循环路径: let radius = 100.0 let circularPath = UI
如何在 1 分钟后停止 setTimeout。由于循环,它继续运行。TIA var image1 = new Image() image1.src = "images/slide1.jpg"
我现在这个问题发布了更多次,但我还没有解决我的问题。在我的例子中,foregroundColor 不工作。即使 foregroundColor 没有选择任何颜色,环也不会出现 darkGray 颜色。
public class Tester { // instance variables - replace the example below with your own Scanne
来自澳大利亚的投票问题: 一个机器人会不断地输入信息,它可以达到 1000 行。他将输入的内容示例: "1 2 3 2 1 3 2 3 1 1 2 3 3 1 2 " 我怎么知道他什么时候输入完信息?
有人可以启发如何进行这项工作吗?所以现在我有一个 do/while 循环,里面有一个开关。开关由一个 int 选择处理,scanf 是“%d”。但是,如果我写一个不同于数字的字符符号,如 a、b、c.
我是一名优秀的程序员,十分优秀!