控制不同的硬件:多线程还是不同的东西?

Posted

技术标签:

【中文标题】控制不同的硬件:多线程还是不同的东西?【英文标题】:Controlling different hardware: multithreading or something different? 【发布时间】:2017-12-12 18:44:23 【问题描述】:

在物联网设备(Linux、ARM、C++)上工作。 现在我正在创建样板代码和一般程序结构。 程序与不同的硬件通信:

板上的 GPIO 引脚。 几个 1-wire 传感器。 I2C 总线上的其他 GPIO 芯片和按键。 通过 RS232 接口连接的设备

现在棘手的部分是 RS232 设备、1-wire 和 I2C 设备的响应速度并不快。这意味着如果我在一个线程上做这样的事情:

    while (!_isShutdown)
    
        for (auto& device : _devices)
        
            device.update();
        
    

我会浪费很多时间和资源,更重要的是,我无法及时完成我的任务,因为多个传感器可能需要长达 500 毫秒才能检索到最新值。

这个问题自然而然地让我想到了多线程。我可以为每个设备创建一个后台线程。这意味着我拥有的设备越多,我将使用的线程和内存(我相信 1MB)就越多。就我而言,仅管理硬件可能需要多达 30 个线程(我也有网络通信,这意味着更多线程)。

我认为也许存在更好的硬件管理方法。也许每次读取执行阻塞时创建一个线程是一个糟糕的设计?如果是这样,有哪些替代方案?网上有很多简单的例子,但对复杂项目有用的资料却很少。

在 Raspberry 内存和执行速度等设备上不是问题,但这可能会导致开发愚蠢和未优化代码的坏习惯。我请你澄清这一点。

【问题讨论】:

如果设备是在文件描述符接口后面抽象出来的,并且通过公共文件readwrite 调用访问,请考虑使用selectepoll。它们允许您在一个线程中同时运行多个 IO 操作。 在tldp.org/HOWTO/text/Serial-Programming-HOWTO 的底部是一个使用select 读取两个串行端口的好例子。 【参考方案1】:

从您的角度来看,您没有准确解释什么是“更好的方法”。正如您所说,内存不是问题,那么为每个设备提供自己的线程可能还不错。尽管内存消耗过多,但这样的代码很容易阅读和调试。

为避免内存消耗,您可能希望从阻塞代码切换到解除阻塞。也就是说,线程不会等待 I/O 操作结束,而是硬件本身通知操作结束,例如带有硬件中断。然后,中断处理程序向其侦听器发送一条消息,这可能导致任务调度在线程池上运行。 C++ 中最成熟的任务库是Intel® Threading Building Blocks。在任务中编程似乎比在线程中更复杂,但更有趣,因为可以使代码更适合预期目标。

【讨论】:

我完全错过了select 的方法。我猜select 用于 I/O 读取与您提到的库(更多高级逻辑)相结合是最终答案。 对了,你对微软的pplx任务(作为cpprestsdk的一部分)有什么看法吗? 以前从未听说过 pplx 任务。阅读:***.com/questions/7515097/…【参考方案2】:

根据我的经验,最灵活和抗更改的方法是使用线程:对于每个总线网络接口,都有不同的线程。最重要的是,我使用 Activity 设计模式,我将在其中以安全的方式将一个对象作为事件处理程序提交给另一个线程。其中一些可以从这里阅读:http://tauria.ee/002/products/gradislib/

【讨论】:

以上是关于控制不同的硬件:多线程还是不同的东西?的主要内容,如果未能解决你的问题,请参考以下文章

python多个线程锁可提高效率吗

用C语言如何实现多线程同时运行的情况下,各个线程输出不同的随机数?

Redis 属于单线程还是多线程?不同版本之间有什么区别?

Linux多线程编程——线程的同步与互斥

什么是进程?和线程区别?

java多线程通过管道流实现不同线程之间的通信