mmap、msync 和 linux 进程终止 [英] mmap, msync and linux process termination

查看:24
本文介绍了mmap、msync 和 linux 进程终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 mmap 来实现在 Linux 下运行的 C 程序中程序状态的某些部分的持久性,方法是使用 mmap() 和 MAP_SHARED 标志集将固定大小的结构与众所周知的文件名相关联.出于性能原因,我宁愿根本不调用 msync(),并且没有其他程序会访问此文件.当我的程序终止并重新启动时,它会再次映射同一个文件并对其进行一些处理以恢复它在终止前所处的状态.我的问题是:如果我从不调用文件描述符上的 msync(),内核是否会保证对内存的所有更新都将写入磁盘并随后可以恢复,即使我的进程因 SIGKILL 终止?此外,即使我的程序从不调用 msync(),内核是否会定期将页面写入磁盘,也会产生一般系统开销?

I want to use mmap to implement persistence of certain portions of program state in a C program running under Linux by associating a fixed-size struct with a well known file name using mmap() with the MAP_SHARED flag set. For performance reasons, I would prefer not to call msync() at all, and no other programs will be accessing this file. When my program terminates and is restarted, it will map the same file again and do some processing on it to recover the state that it was in before the termination. My question is this: if I never call msync() on the file descriptor, will the kernel guarantee that all updates to the memory will get written to disk and be subsequently recoverable even if my process is terminated with SIGKILL? Also, will there be general system overhead from the kernel periodically writing the pages to disk even if my program never calls msync()?

我已经解决了数据是否写入的问题,但我仍然不确定这是否会导致一些意外的系统加载尝试使用 open()/write()/fsync() 并冒着如果进程被 KILL/SEGV/ABRT/等击中可能会丢失一些数据的风险.添加了 'linux-kernel' 标签,希望有知识的人可以加入.

I've settled the problem of whether the data is written, but I'm still not sure about whether this will cause some unexpected system loading over trying to handle this problem with open()/write()/fsync() and taking the risk that some data might be lost if the process gets hit by KILL/SEGV/ABRT/etc. Added a 'linux-kernel' tag in hopes that some knowledgeable person might chime in.

推荐答案

我决定不那么懒惰,通过编写一些代码来回答数据是否最终写入磁盘的问题.答案是会写.

I decided to be less lazy and answer the question of whether the data is written to disk definitively by writing some code. The answer is that it will be written.

这是一个在向 mmap 文件写入一些数据后突然自杀的程序:

Here is a program that kills itself abruptly after writing some data to an mmap'd file:

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef struct {
  char data[100];
  uint16_t count;
} state_data;

const char *test_data = "test";

int main(int argc, const char *argv[]) {
  int fd = open("test.mm", O_RDWR|O_CREAT|O_TRUNC, (mode_t)0700);
  if (fd < 0) {
    perror("Unable to open file 'test.mm'");
    exit(1);
  }
  size_t data_length = sizeof(state_data);
  if (ftruncate(fd, data_length) < 0) {
    perror("Unable to truncate file 'test.mm'");
    exit(1);
  }
  state_data *data = (state_data *)mmap(NULL, data_length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, fd, 0);
  if (MAP_FAILED == data) {
    perror("Unable to mmap file 'test.mm'");
    close(fd);
    exit(1);
  }
  memset(data, 0, data_length);
  for (data->count = 0; data->count < 5; ++data->count) {
    data->data[data->count] = test_data[data->count];
  }
  kill(getpid(), 9);
}

这是一个在前一个程序死后验证结果文件的程序:

Here is a program that validates the resulting file after the previous program is dead:

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

typedef struct {
  char data[100];
  uint16_t count;
} state_data;

const char *test_data = "test";

int main(int argc, const char *argv[]) {
  int fd = open("test.mm", O_RDONLY);
  if (fd < 0) {
    perror("Unable to open file 'test.mm'");
    exit(1);
  }
  size_t data_length = sizeof(state_data);
  state_data *data = (state_data *)mmap(NULL, data_length, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0);
  if (MAP_FAILED == data) {
    perror("Unable to mmap file 'test.mm'");
    close(fd);
    exit(1);
  }
  assert(5 == data->count);
  unsigned index;
  for (index = 0; index < 4; ++index) {
    assert(test_data[index] == data->data[index]);
  }
  printf("Validated
");
}

这篇关于mmap、msync 和 linux 进程终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆