线程的mmap中MAP_PRIVATE和MAP_SHARED之间的差异

时间:2015-10-09 09:36:29

标签: c pthreads mmap

文件的内容'你好'是hello

$ od -tx1 -tc hello 
0000000 68 65 6c 6c 6f 0a
          h   e   l   l   o  \n
0000006

下面是我的代码,对文件进行一些更改' hello'。

static void *task();

int main(void)
{
    int *p;
    pthread_t Thread;
    int fd = open("hello", O_RDWR);
    if (fd < 0) {
        perror("open hello");
        exit(1);
    }
    p = mmap(NULL, 6, PROT_WRITE, MAP_PRIVATE, fd, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    close(fd);
    pthread_create(&Thread, NULL, &task, p)
    printf("Help");
    pthread_join(Thread, 0);
    munmap(p, 6);
    return 0;
}

static void * task(int *r)
{
 r[0] = 0x30313233;
}

上面的代码我使用MAP_PRIVATE,似乎子线程不起作用。 如果我将MAP_PRIVATE更改为MAP_SHARED,我认为这会带来我期望的差异。

$ od -tx1 -tc hello
 0000000 33 32 31 30 6f 0a
           3   2   1   0   o  \n
 0000006

但我不知道它是如何发生的。

2 个答案:

答案 0 :(得分:4)

这与线程无关,如果在主线程中进行了修改,则会得到相同的结果。 MAP_PRIVATE的重点不是将修改传播到底层对象(在本例中是文件)。这在the manual

中有所描述
  

MAP_PRIVATE - 创建私有的写时复制映射。更新到   映射对映射同一文件的其他进程不可见,   并且不会传递到基础文件。它没有具体说明   是否可以看到mmap()调用后对文件所做的更改   在映射的区域。

换句话说,MAP_PRIVATE为您提供了一个内存区域,供您的进程(在其所有线程中)和分叉子进程(它们不会在任何地方写入)的私有使用。您可以将其视为malloc()的替代方案。

答案 1 :(得分:0)

阅读manual总是一个好主意,因为它正好告诉你原因。

  

MAP_SHARED

     

分享此映射。对映射此文件的其他进程可以看到对映射的更新,并将其传递给   基础文件。在msync(2)之前,文件实际上可能不会更新   或者叫munmap()。

     

MAP_PRIVATE

     

创建私有的写时复制映射。映射的更新对映射同一文件的其他进程不可见,和不是   进入底层文件