1

在临界区中修改的共享内存的某些部分包含大量数据,但只有一小部分在单次传递中被更改(例如空闲内存页面位图)。如何确保程序中断/终止时数据保持一致状态。除了拥有两个副本(例如下面示例中的副本和交换或具有某种回滚段)之外,还有什么建议吗?

struct some_data{
  int a;
  int t[100000]; //large number of total data but a few bytes changed in a single pass (eg. free entries bitmap/tree).
};


short int active=0;
some_data section_data[2];

//---------------------------------------------------

//semaphore down

int inactive=active % 2;
section_data[inactive]=section_data[active];

// now, make changes to the section data (section_data[next_active])

active=inactive;

//semaphore up
4

1 回答 1

4

您正在寻找事务一致性:事务全部发生或根本不发生。

一种常见的模式是日志,您可以在其中存储您打算在应用它们时进行的更改。任何访问共享内存并检测到崩溃进程的人(例如注意到他们以某种方式获取了带有部分存在的日志的信号量),在继续之前负责重播日志。

您仍然有一个竞争案例,实际写入一个位信号给所有进程,实际上有一个日志可以使用。但是,这是一个足够小的信息体,您可以通过任何您喜欢的渠道发送它,例如另一个信号量或巧妙地使用栅栏。

最好是日志足够独立于内存状态,以便修复过程可以从日志的开头开始并重播整个事情。如果您必须确定日记中的哪个条目是“下一个”,那么您需要更多的同步。

于 2013-09-14T22:04:45.123 回答