因此,基于粗略搜索,我已经知道从构造函数中调用虚函数(纯函数或其他函数)是不行的.我重新构建了我的代码,以确保我没有这样做.虽然这会导致我的类的用户在他们的代码中添加一个额外的函数调用,但这真的不是什么大不了的事.也就是说,它们不是在循环中调用构造函数,而是调用函数(事实上!)来提高代码的性能,因为我们没有每次构建和销毁相关对象的内务处理.
但是,我偶然发现了一些有趣的事情......
在抽象类中我有这样的东西:
// in AbstractClass.h:
class AbstractClass {
public:
AbstractClass() {}
virtual int Func(); //user can override
protected:
// Func broken up, derived class must define these
virtual int Step1() = 0;
virtual int Step2() = 0;
virtual int Step3() = 0;
// in AbstractClass.cpp:
int AbstractClass::Func() {
Step1();
// Error checking goes here
Step2();
// More error checking...
// etc...
}
Run Code Online (Sandbox Code Playgroud)
基本上,有一个共同的结构,纯虚函数大多数时间都遵循,但如果它们不是Func()是虚拟的,并允许派生类指定顺序.但是,每个步骤都必须在派生类中实现.
我只是想确保在Func()函数调用纯虚函数时,没有什么我在这里做错了.也就是说,使用基类,如果你调用StepX(),就会发生不好的事情.但是,通过创建派生对象然后在该派生对象上调用Func()(例如MyDerivedObject.Func();)来使用该类,该派生对象应该正确地重载所有纯虚函数.
通过这种方法,我有什么遗漏或做错了吗?谢谢您的帮助!
我已经研究了许多有用的线程和一些教程,但我仍然遇到一些应该非常简单的问题.这里参考一些我已经阅读过的主题:
无论如何,我有点问题.如果我收到数据,我的代码工作正常.如果我不这样做,read()函数会停止并且退出程序的唯一方法是使用kill -9(注意:我使用信号处理来向读取串行数据的线程发出信号以终止.这不是罪魁祸首,即使我已经删除了我的信号处理,read()调用仍然停止.我想要做的是读取一次阻塞和读取一个块(因此节省CPU使用率),但是如果读取没有数据,我就不会超时.
以下是我正在应用于端口的设置:
struct termios serial_struct;
serial_struct.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
serial_struct.c_iflag = IGNPAR;
serial_struct.c_oflag = 0;
serial_struct.c_lflag = 0;
serial_struct.c_cc[VTIME] = 1; // timeout after .1s that isn't working
serial_struct.c_cc[VMIN] = 64; // want to read a chunk of 64 bytes at a given time
Run Code Online (Sandbox Code Playgroud)
然后我使用tcsetattr()设置这些设置,并确认端口通过tcgetattr()接收设置.我认为我的设置可能有冲突,因为我的读取似乎是阻塞并等待直到收到64个字节,但是对于超时没有做任何事情.我知道我可以使用select()来处理超时,但我希望避免多个系统调用.
一如既往,感谢您的帮助.
我有一个正在使用的设备驱动程序,它在 ISR(更具体地说是 ISR 的下半部分)和read()调用之间具有共享资源。
ISR 所做的只不过schedule_work()是让下半部分来做繁重的工作。资源在read()(即用户上下文)和实现下半部分的函数之间共享,这就是为什么我用spin_lock_bh().
我不明白的是锁定的机制。假设某人当前持有锁,当 ISR 命中时会发生什么schedule_work()(即,当我们持有锁时触发了硬件中断)?工作是否仍然按计划进行,然后在稍后的时间运行,还是被丢到了地板上?换种说法……实际上“锁定”或阻止了什么(即工作队列或工作的执行)?工作队列是否更新?
为了对比我的问题,我知道如果我正在使用spin_lock_irqsave(),则在持有锁时 ISR 将被禁用,因此我一开始就不schedule_work()会这样做,但是考虑到资源的共享方式,我认为我不需要或想要在持有锁时禁用硬件中断。
我最近接触过GLib并正在玩它.我已经能够用GLib函数替换大量的C库函数(除此之外,我是命令行处理的忠实粉丝!).但是,有一件事我无法找到很多文档来自操作系统的信号处理.即在Linux中,有没有更好的方法可以处理CTRL + C或其他信号来终止应用程序?目前我使用signal(),但我想知道是否有一种方法可以通过GLib为CTRL + C设置我的处理程序.
一如既往,感谢您的帮助.
我有一个问题,我正试图解决Linux中的串口问题.我能够打开,读取和关闭端口就好了.但是,我想确保我是唯一一个在任何时候从港口读/写的人.
在我进行open()函数调用之后,我认为这已经为我完成了.但是,我可以在程序的同一个端口上多次调用open().我也可以有两个线程同时从同一个端口读取.
我尝试用flock()解决这个问题,但我仍然遇到了同样的问题.是因为两个系统调用都来自同一个pid,即使每组打开和读取都涉及不同的文件描述符?对于记录,两个open()调用都返回有效的文件描述符.
结果,我想知道是否有任何方法可以解决问题.从我的程序的角度来看,如果两次调用open()在同一个端口上成功,那么这并不是什么大问题,因为程序员应该知道它们造成的欢闹.但是,我只想确保当我打开一个端口时,我是唯一可以访问它的进程.
谢谢您的帮助.
我想将stdout和stderr重定向到一个套接字,然后可以用来通过以太网远程监视我的应用程序的状态。目前,我通过使用ssh并在shell控制台中查看输出来完成此操作。如果可能的话,我希望删除中间人,然后将整个stdout和stderr输出发送到udp或tcp / ip端口,并将监视计算机连接到该端口。
我不能使用UART或任何其他有线连接。它必须是以太网。另外,如果可能的话,我想通过bash脚本来完成此操作,以防止必须重建我的应用程序。
谢谢您的帮助。
我正在为一些新颖的硬件实现设备驱动程序,并希望一次只允许一个进程访问该设备.并发读/写操作会使硬件混淆到可能需要发生硬复位的程度.我还有以下问题:
在示例代码从Linux设备驱动程序,该open()呼叫使用了锁,但close()没有.这里是不是还有竞争条件,还是scull_s_count保证是原子的减量?基本上,在这个例子中,我想知道如果一个进程试图在另一个进程正在收尾并关闭它时正确地打开设备会发生什么.
我假设我不需要scull_s_count在我read()和write()调用中检查我的开放标志的状态(我正在做类似于示例的事情),因为进入这些调用的唯一方法是用户空间应用程序是否已经收到在fd通过成功调用open().这个假设是否正确?
感谢tadman的评论,我对内核的atomic_t机制进行了粗略的搜索.这是我现在拥有的一些伪代码:
int open(struct inode *inode, struct file *filp) {
spin_lock(&lock);
if (atomic_read(&open_flag)) {
spin_unlock(&lock);
return -EBUSY;
}
atomic_set(&open_flag, 1);
/* do other open() related stuff */
spin_unlock(&lock);
return 0;
}
int close(struct inode *inode, struct file *filp) {
int rc;
/* do close() stuff */
atomic_set(&open_flag, 0);
return rc;
}
Run Code Online (Sandbox Code Playgroud)
这open_flag是一个atomic_t分配的更大结构的一部分kzalloc() …
我正在编写一个设备驱动程序,并希望对一些代码进行基准测试,以了解可能遇到的瓶颈。结果,我想计时一些代码段。
在用户空间,我已经习惯了使用clock_gettime()与CLOCK_MONOTONIC。查看内核源代码(请注意,我正在运行内核4.4,但最终将进行升级),看来我有几种选择:
getnstimeofday()getrawmonotonic()get_monotonic_coarse()getboottime()为了方便起见,我编写了一个函数(请参见下文)以获取当前时间。我目前正在使用,getrawmonotonic()因为我想这就是我想要的。我的函数将当前时间返回为ktime_t,因此我可以ktime_sub()用来获取两次之间的经过时间。
static ktime_t get_time_now(void) {
struct timespec time_now;
getrawmonotonic(&time_now);
return timespec_to_ktime(time_now);
}
Run Code Online (Sandbox Code Playgroud)
给定可用的高分辨率时钟功能(jiffies对我不起作用),对于给定的应用程序,最佳功能是什么?一般来说,我对有关这些功能和基础时钟的任何/所有文档都感兴趣。首先,我很好奇时钟是否受到任何时序调整的影响以及它们的时期。
我目前正在编写一个CUDA应用程序,并且正在遇到一些IO问题"喂养野兽".
我想知道是否有任何方法可以直接从RAID控制器或NIC读取数据并将数据直接发送到GPU.我想要完成的内容直接显示在以下演示文稿的幻灯片#3中:http://developer.download.nvidia.com/devzone/devcenter/cuda/docs/GPUDirect_Technology_Overview.pdf.
话虽如此,显然这已经在这里得到了回答:是否可以直接从gpu访问硬盘?但是,我所附的演示文稿导致相信我所需要的只是在Linux中设置一个环境变量(但它没有提供任何有用的代码片段/示例).
因此,我想知道是否可以直接从NIC/RAID控制器读取数据到GPU中,以及需要做什么?我需要为硬件编写自己的驱动程序吗?是否有任何避免某些副本的例子?
在此先感谢您的帮助.
我有一个类,我想定义[]运算符.该类保存一个串行数据包(以及对所述数据包进行操作的相关功能).我想让用户有能力做这样的事......
MyClass packet;
uint8_t byte = packet[3]; // get third byte of packet
Run Code Online (Sandbox Code Playgroud)
我想阻止用户这样做......
packet[3] = 0xAA; // this breaks encapsulation for my class :(
Run Code Online (Sandbox Code Playgroud)
我一直在寻找解决方案,我想知道这个声明是否就是我所需要的(以及我的.cpp中的相关代码):
const uint8_t operator[](const std::size_t index) const;
Run Code Online (Sandbox Code Playgroud)
虽然我很确定这会起作用,但我仍然对我的方法有一些不确定性,我希望你能解决我的问题.
简单地返回值而不是引用是"可以"吗?我知道在我看过的所有例子中都返回了一个引用.返回值是否有助于我解决这个事实,即我不希望在操作的左侧使用"[]"?那么,const不会阻止这个吗?
即使在非const对象上也会调用const函数吗?我已经看到了一些例子,其中有一个const版本的运算符和一个非const的运算符声明.非const允许写入,而const只允许读取,但只调用const对象.我的目标是让非const对象只能读取.
是否有一种干净的方法来传递操作员的错误?我的主要问题是所请求的数据可能超出了我所拥有的数据范围.我见过的所有示例都使用了断言,但是如果用户对运算符的调用导致某种程度的欢闹,我不一定希望程序崩溃.我也不一定能传回特殊代码,因为我传回的字节的任何值都可能有效.
一如既往,感谢您的帮助,因为我慢慢地(但肯定地)从C程序员到OO C++向导进行了可怕的过渡.
最近我一直在仔细研究我的编程风格以及如何改进它.首先让我说,在我目前的职位上,我是唯一的程序员.结果,我可以把事情做成我想要的hacky,但我真的在努力成为一个更好,更健全的程序员.
另外,我的背景主要是基于C的,基本上在必要时使用C++作为C的超集.结果,我偶然发现了以下难题.
我总是用#define ERROR_FUNCTION_BLEW_UP -2定义错误代码.诚实地说,我可以看到这样做的好处,因为我不需要分配内存来存储-2.但是,在C++中,我可以看到使用const变量的好处,因为两个竞争宏之间的冲突机会较少.
结果,我想知道在C++中实现错误代码的最简洁方法是什么.也就是说,我希望客户端能够通过执行类似于"if(return_value == ERROR_FUNCTION_BLEW_UP)"的操作来检查某些函数的返回值.我已经尝试在每个类中添加一个const变量,但是代码看起来不正确.也就是说,客户端现在检查"if(return_value == MyClass.kErrorFunctionBlewUp_)"行.有没有更简洁的方法来实现这一点,而不是让常数成为班上的公共成员?
另外,要添加到我的问题,myClass是一个基类,现在我想在MyDerivedClass中添加更多错误代码.有什么办法解决这个问题并避免使用宏?
感谢大家的帮助.
我知道对于独立类,你应该避免在复制构造函数中调用赋值运算符.复制和交换以及将重用代码移动到私有成员函数是两种轻松重用代码的方法.但是,最近我遇到了一些问题.这是代码:
// Derived.h
class Derived : Base {
// bunch of fun stuff here
// ...
// constructor that builds a derived object from a base one
explicit Derived(const Base& base);
// Assignment operator for moving base class member variables into the derived one
Derived& operator=(const Base& base);
};
// Derived.cpp
Derived::Derived(const& Base base) {
*this = base; // use assignment operator from derived to base
}
Derived& Derived::operator=(const Base& base) {
static_cast<Base>(*this) = base; // call base class assignment …Run Code Online (Sandbox Code Playgroud) 长话短说,我有一个二维矢量,我需要memcpy().如何获取指向数据结构的第一个元素的指针?
另外,鉴于它在连续内存中,我可以传入这个指针和总大小,对吗?
以下代码是否有效?
vector < vector <int> > vec;
// .. assume it's populate and built up here
int* ptr = vec[0].data(); // use this pointer
Run Code Online (Sandbox Code Playgroud) c ×7
linux ×6
c++ ×5
linux-kernel ×3
const ×2
inheritance ×2
serial-port ×2
console ×1
constructor ×1
cuda ×1
driver ×1
glib ×1
locking ×1
pure-virtual ×1
signals ×1
sockets ×1
stl ×1
vector ×1