我正在设计一个连接到一个或多个数据源流的系统,并对数据进行一些分析,而不是基于结果触发事件.在典型的多线程生产者/消费者设置中,我将有多个生产者线程将数据放入队列,并且多个消费者线程读取数据,并且消费者仅对最新数据点加上n个点感兴趣.如果慢速消费者无法跟上,生产者线程将不得不阻止,当然,当没有未经处理的更新时,消费者线程将被阻止.使用具有读取器/写入器锁的典型并发队列将很好地工作,但是进入的数据速率可能很大,因此我希望减少锁定开销,尤其是生产者的写入锁.我认为我需要一个循环无锁缓冲区.
现在有两个问题:
圆形无锁缓冲是答案吗?
如果是这样,在我自己推出之前,您是否知道任何符合我需求的公共实施?
任何指向实现循环无锁缓冲区的指针总是受欢迎的.
顺便说一句,在Linux上用C++做这件事.
一些额外的信息:
响应时间对我的系统至关重要.理想情况下,消费者线程会希望尽快看到任何更新,因为额外的1毫秒延迟可能会使系统失去价值,或者价值更低.
我倾向于的设计思想是一个半无锁的循环缓冲区,生产者线程尽可能快地将数据放入缓冲区,让我们调用缓冲区A的头部,除非缓冲区已满,否则A满足缓冲区Z的结束.消费者线程将各自保存两个指向循环缓冲区P和P n的指针,其中P是线程的本地缓冲区头,P n是P 之后的第n个项目.每个消费者线程将推进其P和P ñ一旦处理完当前P和缓冲器指针Z的端前进具有最慢P ñ.当P赶上A,这意味着没有更新的处理更新,消费者旋转并忙着等待A再次前进.如果消费者线程旋转太长时间,它可以进入休眠状态并等待条件变量,但我没关系消费者占用CPU周期等待更新,因为这不会增加我的延迟(我会有更多的CPU核心)比线程).想象一下,你有一个循环轨道,并且生产者正在一群消费者面前运行,关键是调整系统,使生产者通常比消费者领先一步,并且大部分操作都可以使用无锁技术完成.我理解获得正确实施的细节并不容易......好吧,非常难,这就是为什么我想在自己制作一些错误之前先从别人的错误中吸取教训.
组织项目目录的一种流行方式或多或少是这样的:
MyLib +--mylib_class_a.h mylib_class_a.cpp mylib_library_private_helpers.h mylib_library_private_helpers.cpp MyApp +--other_class.h other_class.cpp app.cpp
app.cpp
:
#include "other_class.h"
#include <mylib_class_a.h> // using library MyLib
Run Code Online (Sandbox Code Playgroud)
同一个库的所有.h
和.cpp
文件都在同一目录中.为避免名称冲突,文件名通常是公司名称和/或库名称的前缀.MyLib将位于MyApp的标题搜索路径等中.我不是前缀文件名的粉丝,但我喜欢查看#include
并确切知道头文件所属的位置.我不讨厌这种组织文件的方法,但我认为应该有更好的方法.
自从我开始一个新项目以来,我想征求一些目录组织的想法.目前我喜欢这个目录结构:
ProjA +--include +--ProjA +--mylib +--class_a.h +--app +--other_class.h +--src +--mylib +--class_a.cpp library_private_helpers.h library_private_helpers.cpp +--app +--other_class.cpp app.cpp util.h
app.cpp
:
#include "util.h" // private util.h file
#include <ProjA/app/other_class.h> // public header file
#include <ProjA/mylib/class_a.h> // using class_a.h of mylib
#include <other3rdptylib/class_a.h> // class_a.h of other3rdptylib, no name collision
#include <class_a.h> // not ProjA/mylib/class_a.h
#include …
Run Code Online (Sandbox Code Playgroud) c++ version-control directory-structure code-organization project-organization
我需要通过互联网上的http下载一些csv文件,解析它并将其转换为更有用的fomat.最终,C++程序将使用数据.几年前,我将提取我的Perl书籍并开始编写Perl脚本来进行下载和解析.但是现在有了Boost和Qt,我可以用很少的努力在C++中进行下载,解析和投入GUI前端.上次我写Perl/Python大约是6个月前.在Perl/Python中执行它可能需要更长的时间,而我的Perl/Python代码将是垃圾.如果我唯一的工具是锤子,一切看起来像钉子?或者时间已经改变,C++在传统上由Perl或Python等脚本语言主导的领域可以高效生产?
我想知道我的想法.我想问你是否知道任何与此相关的图书馆或文章.或者你可以告诉我这是一个愚蠢的想法,为什么.
我有一个类,我想在运行时动态地添加方法/属性.我很清楚使用复合/命令设计模式和使用嵌入式脚本语言来完成我所说的技巧.我只是在探索这个想法.没必要说这是个好主意.
class Dynamic
{
public:
typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap;
void addMethod(const std::string& name, boost::function<void (Dynamic&)> func) {
funcMap_[name] = func;
}
void operator[](const std::string& name) {
FuncMap::iterator funcItr = funcMap_.find(name);
if (funcItr != funcMap_.end()) {
funcItr->second(*this);
}
}
private:
FuncMap funcMap_;
};
void f(Dynamic& self) {
doStuffWithDynamic(self);
}
int main()
{
Dynamic dyn;
dyn.addMethod("f", boost::bind(&f, _1));
dyn["f"]; // invoke f
}
Run Code Online (Sandbox Code Playgroud)
我的想法是我可以在运行时将名称"f"重新绑定到任何函数.我知道字符串查找和boost :: function与原始函数指针的性能问题.通过一些努力工作和非便携式黑客攻击,我认为我可以减轻性能问题.
使用相同类型的技术,我可以通过使用"v-table"进行名称查找和基于动态运行时属性的调度函数调用来执行"运行时继承".
如果只想告诉我使用smalltalk或Objective-C,我可以尊重这一点,但我喜欢我的C++并且我坚持使用它.