啊,船长,我们现在正对着港口。我们什么时候开始炮击,抢劫和混乱?
现在,别开枪,热裤,我们有三艘船在执行任务,我不希望任何人拿着焦躁不安的扳机跳枪,听到了吗?而且,在你这么做之前,我现在要告诉你:不要批评我的混血儿。
啊,是的,船长。哦,我们在港口发现了一艘我们没有预料到的额外战舰。我需要有人从下面多拿些炮弹来,因为我们用的炮弹可能比想象的要多。我们能让其他飞船也这么做吗?
我可以让紫色瘟疫号上的人去取更多,毕竟这是我的船。但是匹金普里斯,嗯,那是老死虫的。他自行其是。我不能对他的人发号施令,他也不听任何人的建议。他得自己想办法。
啊,是的,船长。我在瘟疫号上发出信号。
[信号,没有反应]
啊,船长,我没有从那些懒鬼那里得到任何回应。
唉,螃蟹,看在罪犯的份上,我不让它们暂停平时的午睡时间!我为什么要让他们试验他们所谓的"人体工程学海盗实践"我脑子这么笨,膝盖这么笨,真该被人用龙骨钉死!我们现在进退两难,在他们恢复电力之前我们什么都做不了。啊,好吧,那现在也没办法了。只是需要等待。让大家都站起来做俯卧撑什么的。
啊,是的,船长。
从前,生活很简单。*有一个CPU进行计算,可以编写程序告诉CPU要做什么。这些程序可能需要来自CPU周围的资源,这是可以的,因为有一个操作系统来管理这些资源,程序只需要向操作系统询问它需要什么,就可以工作了。(好吧,除非你不得不重新启动系统,因为,嗯,因为你不得不这样做,因为它停止工作了。)
然后我们开始增加核心。但是所有的核心都可以保持在一个单一的操作系统的控制下,该操作系统平等地对待它们,并为每个内核分配工作,处理它们的任何资源需求。
然后我们开始挑剔哪些核心最适合什么目的,一些核心开始担心其他核心可能会在他们需要的时候占用他们的资源,所以他们需要自己的私人资源和按摩治疗师。他们可能如果别人很友好,让他们使用,并先征得他们的同意。其他无政府主义核心决定告诉他们的操作系统:“嘿,你不是我的老板!然后就把操作系统关掉了。其他核心决定帮系统降低功耗,时不时地小睡一会儿。
听起来像是一群五岁小孩,青少年或者海盗。
因此,你的随机程序最终会遇到一个问题,它可能需要在特定的核心上运行,并访问特定的资源,这些资源可能属于或不属于该核心,甚至可能不存在或在需要时处于唤醒状态。
再加上嵌入式系统的环境,其中资源是稀缺的,时间是至关重要的。
另外一个问题是,有些程序和系统很简单,不希望被复杂系统可能需要的冗长程序所困扰。
因此,或多或少,您将面临多核协会正在用他们刚刚发布的多核资源API (MRAPI)规范解决的问题。请注意,与兄弟多核通信API (MCAPI)几年前的标准。
其思想是允许轻量级的基础设施,为程序员提供更好的管理资源的方法。但是,对于简单的系统来说,它只是一个API: API是如何实现的,很大程度上是留给系统设计者的,在需要的地方允许复杂,在可能的地方避免复杂。
MRAPI构建在MCAPI域和节点概念之上,并添加了三个基本实体:同步、内存和系统资源元数据。
同步帮助处理两个海盗试图在同一时间发射同一门大炮。这让他们玩得很友好:一个先得到独家使用,然后是另一个。该标准定义了三种机制:互斥锁、信号量和读写锁。
互斥对象(难道不应该是“mutices”吗?)代表了最简单、最低级别的同步。这是一个简单的二进制锁。就当这是“权利”吧。在所有者移除锁之前,其他任何人都不能访问该资源。资源实际上可以递归锁定——也就是说,第一个锁的所有者可以添加单独的锁,这些锁必须按顺序删除。感觉有点像普通曼哈顿公寓门上的12个门栓。
下一步是信号量。这允许分配一个资源的多个实例。如果存在8个whatever,那么信号量最多可以发出8个锁,然后才需要等待另一个锁释放。信号量通常不知道哪些资源正在被使用;他们只知道有多少。
最后,读取器/写入器锁可以解决可能有许多读取器和少数简短写入器的情况。读取器/写入器锁必须处理多个并发(即虚拟并发)读操作被写入操作中断的情况。因此,当请求一个锁时,它要么是读取器(共享)类型,要么是写入器(独占)类型。大多数情况下可以很容易地授予读锁,但是,如果有人正在等待写锁,那么在授予写锁之前不能颁发新的读锁。
下一个是内存问题,这些问题有两种:共享的和远程的。共享内存听起来似乎已经解决了问题,因为它可以通过POSIX调用来处理。但这只适用于一个操作系统实例。如果物理内存由不同操作系统下的不同线程共享,POSIX将不起作用;这就是MRAPI的用武之地。
远程内存稍微复杂一些。它在概念上类似于共享内存,不同之处在于,它们不是单一的共享内存块,而是不同的内存。所以核心1可能需要访问由运行在核心2上的操作系统管理的内存。如果内存可以被两个内核物理访问,这就比较简单了。因为MRAPI运行在操作系统之上,所以它可以使用它们来获得适当的地址。
如果核心1在物理上不能访问核心2的内存块,那么必须创建一些DMA或其他机制来创建一个可被核心1访问的远程内存的副本。API读写调用支持这一点,包括分散/聚集读写。后者从多个不相交(但间隔均匀)的区域读取或写入。每一次这样的读或写都是一次“跨步”;简单的读或写是退化的情况,只有一个步幅。
因为您使用的可能是原始数据的副本,所以该副本可能会过时。因此,提供flush和sync调用以允许应用程序本身保持一致性。
最后,一个系统资源元数据提供设施。这是一种简单的方法,用于构建资源存在的映射(通常是树),并且完全依赖于实现。静态系统可以使用XML文件或其他简单的方式存储配置;然后,可以在初始化时读取该选项,以便在系统运行时使用。配置甚至可以编译到MRAPI实现中。
另一方面,对于资源可能进出的系统(由于插拔事件或上电/下电事件),系统设计人员可以提供一种查询活动资源的方法,然后将其附加到API调用。资源树只能作为一个整体来构建;您不能增量地从树中添加或删除分支,因此如果无法访问某个资源,则不能将其从树中删除:必须重新构建整个树。
所以,有了MRAPI的自定义盗版实现,我们不幸的船长就有办法从老死虫那里申请更多的炮弹。他本可以有更好的方法来确定紫色瘟疫已经关闭了。这意味着他可以放松一点,站在那里敲他的树桩,嚼他的钩子……
*似乎我们之前在不止一个场合说过。不,不是渴望回到大草原的生活……非常渴望……
更多信息:MRAPI工作小组(附下载连结)
哦,我只想再说一遍(带着感情!):啊啊啊啊啊啊啊啊