Hacker News new | ask | show | jobs
by jstimpfle 1613 days ago
What is my solution to what? To database I/O? I guess that's what the article is about...
1 comments

I said "lock free memory based interprocess communication"

You said "There is no need for file-backed memory to do that."

If that is true, I want to know what you are talking about, so I'm just asking you to back up the claim you made.

No. _I_ want to know what we're talking about, as my original question clearly indicates.

You can do "lock-free memory based interprocess communication" with memory (obviously). There is no need to back this memory with files, certainly not files on a hard drive that you would otherwise access using read() and write(). Hence my original question.

_I_ want to know what we're talking about

lock free memory based interprocess communication (copied from my first reply)

There is no need to back this memory with files

Again, I'm interested in how you have two processes read and write lock free directly to the same memory if you don't use a memory mapped file.

You have said it isn't necessary, I'm just asking you to back up this claim and explain exactly what you mean.

First, I didn't assume it a requirement to have two processes read() and write() _directly_ to the same memory (I suppose you meant "file region" here). And idk, it might not be a good idea to require that.

Also, you can use normal (non-file-backed) memory to do the necessary synchronization (lock-free or not). I'm still not seeing why the memory should be backed by a file, that's why I was genuinely asking. One reason why it could be practical that I can now see could be for an embedded database like sqlite, but again I'm not sure it would be a good idea. While it would allow for pretty much setup-less synchronization of otherwise uncoordinated processes, it's a fringe application that might be better implemented with one big flock(). And one reason why it could be not a good idea is that it might couple the file format to a particular CPU architecture.

Another big issue I guess is that the atomics actually do have an effect to the underlying file whenever the pages are flushed. What if the computer shuts down unexpectedly? The synchronization affairs aren't cleaned up, yet the original processes are gone.

that's why I was genuinely asking.

You weren't asking, you were saying it wasn't necessary, which you did in the sentence right before this one:

Also, you can use normal (non-file-backed) memory to do the necessary synchronization (lock-free or not).

Again, this is just a repeated claim, it isn't an explanation. How do you have two processes writing to the same place in memory without memory mapping a file?

have two processes read() and write() _directly_ to the same memory

I didn't say read() and write() I said read and write as in reading and writing with memory addresses. Again, this is all about lock free interprocess communication. You can't write outside your own memory from a process with normal permissions so how do you share memory with another process?

You memory map the same file. This isn't about the file being written to some sort of persistent storage, that happens on the OS level and doesn't interfere with two running processes communicating with each other. The file can be deleted after the last process closes it. It is just a way for the two processes to have memory mapped into their virtual memory space that overlaps with each other.

You need to deal with memory directly so you can use atomics. You need to use atomics so you can avoid locks.

I thought you might have had some other technique that I'm not aware of but it seems now you were making claims without much behind them, which is disappointing.

> How do you have two processes writing to the same place in memory without memory mapping a file?

In increasing order of modernity: System V SHM, POSIX SHM, and `mmap(... MAP_SHARED | MAP_ANONYMOUS ...)` (e.g., on Linux).

> You weren't asking, you were saying it wasn't necessary, which you did in the sentence right before this one:

quoting my OP: " Why do you need lockless atomic updates to a file-backed memory area? Genuinely curious. " . Dude.

> it seems now you were making claims without much behind them, which is disappointing.

Well thank you very much.

I get the feeling we might just be talking about the same thing. Or we might be not, I'm not sure.

> How do you have two processes writing to the same place in memory without memory mapping a file?

> You can't write outside your own memory from a process with normal permissions so how do you share memory with another process?

For example on Linux, use shm_open() + mmap(). This is just an example, and granted it uses a file-like API (shared memory objects show up on /dev/shm on a typical Linux) but it is not "file-backed" (I meant disk backed and this might be the misunderstanding) and in particular it's certainly not mapping the database file. It's just one way on one OS to map the same physical memory into different processes' address spaces.

If this example approach is "file-backed" to you, then so be it but I think you have willfully misread my comments up to here.

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

    int main(int argc, const char **argv)
    {
            int fd = shm_open("/TESTOBJECT", O_CREAT | O_RDWR, 0664);
            if (fd == -1)
            {
                    perror("shm_open()");
                    exit(1);
            }

            if (ftruncate(fd, 4) != 0)
            {
                    perror("ftruncate()");
                    exit(1);
            }

            void *mapping = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

            if (mapping == MAP_FAILED)
            {
                    perror("mmap()");
                    exit(1);
            }

            volatile int32_t *ptr = mapping;

            for (;;)
            {
                    printf("%d\n", (int) *ptr);
                    if (argc > 1)
                        *ptr = rand();
                    sleep(1);
            }

            return 0;
    }