jak*_*om2 8 c++ java serialization multithreading systemc
我正在努力研究将执行程序的状态存储到磁盘并将其重新引入的基本原则.在我们当前的设计中,每个对象(具有函数指针列表的C级事物,低级自制的面向对象 - 以及这样做的非常好的理由)将是调用将其显式状态导出为可写和可恢复的格式.使这项工作的关键属性是与对象相关的所有状态确实封装在对象数据结构中.
还有其他解决方案,您可以使用活动对象,其中有一些用户级线程附加到某些对象.因此,程序计数器,寄存器内容和堆栈内容突然成为程序状态的一部分.据我所知,没有什么好方法可以在任意时间点将这些东西序列化到磁盘上.线程必须将其自身停放在一些特殊状态,其中程序计数器等没有任何表示,因此基本上将它们的执行状态机状态"保存"到显式对象状态.
我查看了一系列序列化库,据我所知,这是一个通用属性.
核心问题是:或者这实际上不是这样吗?是否存在可以包含线程状态的保存/恢复解决方案,就其代码中的线程执行位置而言?
请注意,在虚拟机中保存整个系统状态不会计算,这不是真正序列化状态,而只是冻结计算机并移动它.这是一个明显的解决方案,但大多数时候都有点重量级.
有些问题清楚表明,我在解释我们如何做事的想法时并不够清楚.我们正在开发一个模拟器系统,允许编写非常严格的内部代码运行规则.特别是,我们在对象构造和对象状态之间进行了完全划分.每次设置系统时都会重新创建接口函数指针,而不是状态的一部分.状态仅由特定的指定"属性"组成,每个属性具有定义的get/set函数,该函数在内部运行时表示和存储表示之间进行转换.对于对象之间的指针,它们都被转换为名称.所以在我们的设计中,一个对象可能会在存储中出现:
Object foo {
value1: 0xff00ff00;
value2: 0x00ffeedd;
next_guy_in_chain: bar;
}
Object bar {
next_guy_in_chain: null;
}
Run Code Online (Sandbox Code Playgroud)
链接列表从未真正存在于模拟结构中,每个对象代表某种硬件单元.
问题是有些人想要这样做,但也有线程作为编码行为的方式.这里的"行为"实际上是模拟单元状态的变异.基本上,我们所设计的设计说,所有这些变化都必须在原子完整的操作中进行,这些操作被调用,完成它们的工作并返回.所有状态都存储在对象中.您有一个被动模型,或者它可以被称为"运行到完成"或"事件驱动".
另一种思考方式是让对象具有活动线程,它们以与传统Unix线程相同的方式处于永久循环中,并且永不终止.这是我试图看看它是否可以合理地存储到磁盘的情况,但是如果没有在下面插入VM,这似乎是不可行的.
更新,2009年10月:与此相关的论文发表在2009年的FDL会议上,参见本文关于检查点和SystemC.
您不应该尝试将程序必须写入磁盘的状态序列化。因为除非操作系统允许,否则您的程序永远不会完全控制其状态,在这种情况下......它是操作系统的一部分。
您不能保证指向某个虚拟内存位置的指针将再次指向相同的虚拟内存位置(除了堆开始/结束、堆栈开始等属性),因为对于程序来说,操作系统对虚拟内存的选择是不确定的。您通过 sbrk 或更高级别的接口(例如 malloc)从操作系统请求的页面将从任何地方开始。
更好的:
我怀疑您想缩短序列化/反序列化特定数据结构(例如链表)所需的开发时间。请放心,您尝试做的事情并不是微不足道的,而且需要做很多工作。如果您坚持这样做,请考虑研究操作系统的内存管理代码和操作系统的分页机制。;-)
由于附加问题进行编辑:您所说的设计听起来像是某种状态机;对象属性设置为可序列化,可以恢复函数指针。
首先,关于对象中的线程状态:仅当存在典型的并发编程问题(例如竞争条件等)时,这些状态才重要。如果是这种情况,您需要线程同步功能,例如互斥体、信号量等。然后您可以随时访问属性以进行序列化/反序列化并且安全。
其次,关于对象设置:看起来很酷,不确定您是否有二进制或其他对象表示。假设二进制:如果您可以表示内存中的实际结构(这是一点编码开销),您可以轻松序列化它们。在对象的开头插入某种类 ID 值,并有一个指向实际服装的查找表。查看第一个 sizeof(id) 字节,您就知道您拥有哪种结构。然后你就会知道那里有哪个结构。
序列化/反序列化时,请像这样解决问题:您可以查找假设打包(成员之间没有间距)结构的长度,分配该大小并依次读/写成员。考虑 offsetof 或者,如果您的编译器支持它,则只需使用打包结构。
由于大胆的核心问题进行编辑:-)不,没有;不适合C。
| 归档时间: |
|
| 查看次数: |
1469 次 |
| 最近记录: |