简体   繁体   中英

Transfering a file in chunks using POSIX shared memory and semaphores

Full disclosure: although this isn't for a class, it's a simplified example pertaining to a problem I had with an earlier assignment (now passed).

Consider transferring a file between two processes using POSIX shared memory. The producer process shares reads from a file and writes it, by chunks, to a shared memory region; the consumer process reads a chunk of bytes from the region and writes it out (eg to a file). At first I tried a naive method of synchronization -- just locking access to shared memory in a semaphore -- but of course that allowed multiple reads/writes for a single write/read.

I think I've worked out one method of doing this, by using a second shared memory region that blocks access to the reader or writer depending on its current value. Then, in pseudocode:

before request begins:
    initialize shared memory region SHM
    initialize synchronization region SHM2 = "0"
    initialize sem

consumer:
    loop until total bytes read = file length:
        while (SHM2 == "0" [lock access to SHM2 while checking]):
            wait

        read N bytes from SHM
        write N bytes to file

        sem_wait(sem)
        set SHM2 = "0"
        sem_post(sem)

producer:
    loop until total bytes written = file length:
        while (SHM2 == "1" [lock access to SHM2 while checking]):
            wait

        read N bytes from file         
        send N bytes to shared memory

        sem_wait(sem)
        set SHM2 = "1"
        sem_post(sem)

But this seems unwieldy. I'm trying to work on some way to avoid spinning while waiting for the other process, and maybe there's some way to use POSIX synchronization facilities in a way I haven't gotten my head around. Is there something like a condition variable for separate processes? Or another straightforward way of accomplishing this?

You need two semaphores. Each process takes its semaphore, and signals the partner's one:

initialize sem EMPTY to 1
initialize sem FULL to 0

consumer:
    loop:
        sem_wait(FULL)
        consume data
        sem_post(EMPTY)

producer:
    loop:
        sem_wait(EMPTY)
        produce data
        sem_post(FULL)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM