我在c ++中编写了一个程序(假设是X),它创建了一个数据结构然后连续使用它。 现在我想修改该数据结构而不中止以前的程序。 我尝试了两种方法来完成这项任务:
在同一个程序X中,我首先创建了数据结构,然后尝试创建一个子进程,该进程为某种目的开始访问和使用该数据结构。父进程继续执行,并要求用户进行任何修改,如插入,删除等,并从控制台获取输入,然后进行修改。这里的问题是,它不会修改子进程正在使用的数据结构的副本。后来,我发现这无济于事,因为子进程正在使用自己的数据结构副本,因此通过父进程进行的修改不会反映在其中。但绝对是,我不希望这种情况发生。所以我去了多线程。
我没有创建子进程,而是创建了另一个访问该数据结构并使用它的线程,并尝试从不同线程的控制台获取用户输入。甚至, 由于线程之间的切换非常快,因此无法正常工作。
所以,请帮我解决这个问题。我希望修改能够反映在原始数据结构中。此外,我不希望这个过程(正在连续访问和使用它)等待,因为它是时间关键。
答案 0 :(得分:0)
第一点:这是不一个微不足道的问题。要完全处理它,你需要设计一个系统,而不仅仅是一两个快速的黑客。
首先,为了支持动态更改,您几乎肯定希望在代码中定义类似DLL或.so的数据结构,因此您可以动态加载它。
如何继续的部分取决于您是在谈论严格存储在内存中的数据,还是更多面向文件的数据。在后一种情况下,一些决定将取决于数据结构的新形式是否大于旧形式(即,您是否可以升级或不升级)。
让我们开始简单,假设你只处理内存中的结构。每个数据项将表示为一个对象。除了访问数据所需的任何内容之外,每个对象都将提供锁定,以及从对象的先前版本的对象构建自身的方式(懒惰 - 即,按需,而不仅仅是在ctor中)。 p>
当您加载定义新对象类型的DLL / .so时,您将创建一个与当前现有对象集合大小相同的集合。每个新对象都处于“懒惰”状态,在该状态下初始化,但尚未真正从旧对象创建。
然后,您将启动一个线程,该线程使得新集合为程序的其余部分所知,然后遍历新对象的集合,锁定旧对象,使用它创建新对象,然后销毁旧对象并将其从旧集合中删除。当它试图锁定旧对象时,它将使用相当短的超时(即,如果一个对象正在使用,它将不会等待很长时间,只是继续下一个。它会反复迭代直到所有旧对象已更新,旧对象的集合为空。对于磁盘上的数据,除了对象集合提供对磁盘上数据的访问之外, 的内容几乎相同。您可以创建两个单独的文件,并将数据从一个文件复制到另一个文件,并根据需要进行转换。
另一种可能性(特别是如果数据可以就地升级)是使用单个文件,但是在每个记录中嵌入版本号。读取一些原始数据,检查版本号,并使用适当的代码进行读/写。如果您正在读取旧版本号,请使用旧代码阅读,转换为新格式,然后以新格式书写。如果没有空间进行更新,请将新记录写入文件末尾,并更新索引以指示新位置。
答案 1 :(得分:0)
您的并发访问方法类似于在蒙着眼睛的幼儿教室之间共享蛋糕。你最终遇到了一团糟,这并不奇怪。每个幼儿要么必须等待轮到他们,要么确切地知道她自己可以触摸到的蛋糕的哪一部分。
转换为代码,前者意味着拥有一个锁或mutex来控制对数据结构的访问,这样只有一个线程可以随时修改它。
后者可以通过具有由线程修改的数据结构来完成,每个线程确切地知道它们可以更新的数据结构的哪些部分,例如,通过传递一个结构,其中包含要更新的范围的详细信息,有效地预先分割数据。这些不应该重叠,迭代器不应该无效(例如通过调整大小),这对于给定的问题可能是不可能的。
处理资源竞争的算法很多,因此大大简化了这一点。 Distributed computing是致力于解决这些问题的重要计算机科学领域;研究问题(你没有提供细节)并且不要期待魔法。