异步使用设备的高级线程用法

时间:2018-03-22 07:05:35

标签: c++ multithreading asynchronous future

我需要在我的程序中使用多个设备,我希望这可以在高级线程API上完成 通常,与设备的通信包括发送命令和接收答案(通过套接字,串行端口等)。

主要问题是与设备的通信无法放置在GUI(主)线程中,因为没有设备立即响应。

现在,我决定与设备on asynchronous operations进行所有通信,例如使用std::asyncstd::future我的主框架(Qt 5)有自己的&# 34;异步" - QtConcurrent::run()QFuture等,但它也没有提供线程选择。下一个问题是我将始终只在一个附加线程中使用所选设备,

因为:

  1. 我不想制作每个设备'类线程安全,并使用单独的线程可以决定这一点,在我看来。
  2. 我不想考虑不同io接口实现的线程安全性(例如,Serial port in Qt不能在多个线程中打开,但它只是细节)。
  3.   

    注意:串口总是以独占访问方式打开(也就是说,没有其他进程或线程可以访问已打开的串口)。

    1. 如果可能,我希望使用高级线程API,并且不想使用低级线程基元。
    2. 不想将所有设备对象移动到另一个线程中,因为它只是一个大的"上帝"包装
    3. 我看到了下一个选项:

      1. 找到一种在目标特定线程中运行所有必要异步操作的方法(最好)。
      2. 查看其他类似的概念,例如“任务”
      3. 写我自己的" asyncable"线程类

        附加说明:我不想使用仅限事件驱动的逻辑。

      4. 我现在想的是什么(简化) 标题:

        #include <future>
        using namespace std; //
        
        struct TStatus
        {
            bool health;
        };
        
        class AsyncDevice
        {
        public:
            AsyncDevice(IODevice* ioDevice);
            future<TStatus> getHealthStatus();
        
        private:
            TStatus get_health_impl();
        
        private:
            IODevice*       m_ioDevice;
            EventHandler*   m_eventHandler; // Observer to notify
        };
        

        CPP:

        future<TStatus> AsyncDevice::getHealthStatus()
        {
            // ** Here I cannot use choose one specified thread ***
            future<TStatus> ret = async(launch::async, 
                &AsyncDevice::get_health_impl, this);
        
            return ret;
        }
        
        TStatus AsyncDevice::get_health_impl()
        {
            writeDeviceCmd();
            waitForBytesWritten();
        
            // Here it is easy and simply to wait, read and check an answer
            TStatus status;
        
            int timeout = 500;
            if (waitForReadyRead(timeout))
            {
                status = readDeviceAnswer();
            }
            else
            {
                status.health = false;
            }
        
            m_eventHandler->onHealthStatus(status); // Notify observer
            return status;
        }
        

        我的主要问题:
        对于这类问题,最佳解决方案是什么?你能解释一下吗?

1 个答案:

答案 0 :(得分:0)

您正在使用Qt,并且所有使用Qt API的IO都是异步完成的。例如 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress 立即完成并且没有阻塞。当有数据准备好被读取时,Qt信号QIoDevice::read被触发,如果你附加一个插槽,你将能够得到你的数据。这意味着您可以在qt上的GUI线程中执行io,并且不需要为此生成新线程。