0

The content of file 'hello' is hello.

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

Below is my code to make some changes to the file '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;
}

The code above I used MAP_PRIVATE, and it seems that the child thread does not work. If I change MAP_PRIVATE to MAP_SHARED, I see it makes the difference I expect.

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

But I have no idea how it happens.

kaylum
  • 13,833
  • 2
  • 22
  • 31
HuangJie
  • 1,488
  • 1
  • 16
  • 33
  • `man mmap: MAP_PRIVATE Create a private copy-on-write mapping. Updates to the mapping [...] are not carried through to the underlying file.`. Also, you're violating strict aliasing. – EOF Oct 09 '15 at 09:47
  • @EOF Thanks for your reply. I have realized my problem... – HuangJie Oct 09 '15 at 09:52

2 Answers2

7

This has nothing to do with threads, you would have the same result if you did the modification in the main thread. The whole point of MAP_PRIVATE is not to propagate the modification to the underlying object (in this case, the file). This is described in the manual:

MAP_PRIVATE - Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.

In other words, MAP_PRIVATE gets you a region of memory for the private use of your process (in all its threads) and the forked subprocesses, which will not be written anywhere. You can think of it as an alternative to malloc().

user4815162342
  • 141,790
  • 18
  • 296
  • 355
2

Always a good idea to read the manual as it tells you precisely why.

MAP_SHARED

Share this mapping. Updates to the mapping are visible to other processes that map this file, and are carried through to the underlying file. The file may not actually be updated until msync(2) or munmap() is called.

MAP_PRIVATE

Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file.

kaylum
  • 13,833
  • 2
  • 22
  • 31