【发布时间】:2018-05-07 12:19:41
【问题描述】:
通常,我会通过以下方式解决此问题:
task = _taskProvider.getNextFromQueue();
if (task.id == TaskExecutor.TasksEnum.One) {
_taskExecutor.executeTaskOne();
return;
} else if (task.id == TaskExecutor.TasksEnum.Two) {
_taskExecutor.executeTaskTwo();
return;
} else if (task.id == TaskExecutor.TasksEnum.Three) {
_taskExecutor.executeTaskThree();
return;
}
//and so on...
如果需要,我可以将 if-else 切换为 switch。
我确实相信存在更好的方法来实现类似的代码。
想到的一件事是使用表(映射)来存储任务 ID 和指向相应函数的指针,但我不确定它是否有用并提供足够的性能。
我关心的另一件事是通知机制。当TaskProvider 和TaskExecutor 是在不同线程上运行的两个独立实体时,就会出现此问题。如果几个动作需要一些时间来完成执行,情况会变得更糟,我需要创建一个逻辑来让调用者等待结果。
例如,如果executeTaskTwo() 需要一些时间才能完成,我将在后台线程中执行它,这意味着executeTaskTwo() 将几乎立即返回,而任务本身仍将执行。但是一旦结束,我如何通知调用者它的完成?
我猜该解决方案涉及大量修改,也许是一些事件库(我以前从未使用过这些)。我需要一个起点。我想存在某种模式,但我不知道到底是哪一种。
更新 1:
有关一般架构和问题的更多信息 共有三个实体:
-
Hardware- 管理硬件信号(输入、输出)。只关心硬件,不问为什么? -
Network- 管理与设备的远程连接。只关心数据传输。同样,它并不关心数据代表什么。 -
Controller- 控制实际设备的任务/算法(此设备的功能)。这是设备的大脑。
每个实体都在自己的线程上运行。有时,发生了一个事件,一个实体需要将此事件发送给另一个实体(或所有实体)。例如,来自network 的命令会打开某个由硬件管理的 LED,或者,如果未能打开此 LED,应同时向network(通知远程客户端)和controller(执行紧急停止)发出信号。
现在每个实体(类)都有一组函数(方法),其他实体在这个实体做某事时会调用这些函数(方法)。如果调用的函数需要时间来执行,那么调用者实体就会被阻塞,这是不好的。产生后台线程来处理每个命令(或事件)也感觉不对。
目前每个实体都有自己的命令队列并按顺序执行其命令 (execute(queue.getNext())),但由于有些命令执行速度很快,而另一些则需要时间和资源,因此效果不佳。
【问题讨论】:
-
是的,我肯定会在这里使用地图。例如
TasksEnum.Three和executeTaskThree之间的映射可以正常工作。如果您有大量命令,则地图查找实际上可能比if...elses 更快,因为它不需要对每个命令进行线性搜索。 -
你可以传递一个指向函数的指针。
标签: c++ multithreading events design-patterns notifications