0

I have 2 semaphores. I have a shared memory segment. I am trying to synchronize processes so that they wait for each other until a certain task is finished but when sem_post_util( sem_sync ) is used in the other processes just stop and the last processes continues and exits. Why doesn't it increment the unnamed semaphore in the shared memory?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils.h"
#include <signal.h>

#define SHARED_MEM "/shmm115"
#define SEM "nammed_sem115"
#define SEM_SYNC "unnamed_sem115"
#define SIZE 256
#define n_proc 3

sem_t *sem, sem_sync;
void* addr;

void cleanup(){
    sem_close( sem );
    sem_close( &sem_sync );
    munmap_util( addr, SIZE );
    shm_unlink( SHARED_MEM );
}

int main(){
    sem = sem_open( SEM, O_CREAT, 0666, 1 );/*opent the named semaphore we got*/

    /*Open shared memory segment and put a shared variable inside of it*/
    struct sigaction handler;
    handler.sa_handler = cleanup;

    sigaction( SIGINT, &handler, NULL);

    int fd;
    short count = 0;
    fd  = shm_open_util(SHARED_MEM, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | S_IRWXU);

    struct stat stat_buf;
    fstat( fd, &stat_buf );
    if( stat_buf.st_size == 0){/*if it is the first one to write to it*/
        ftruncate_util(fd, SIZE);
        addr = mmap_util(0, SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
        memcpy( addr, &count, sizeof(short) );
        memcpy( addr+sizeof(short), &sem_sync, sizeof(sem_t) );
    }
    else
        addr = mmap_util(0, SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);

    close(fd);
    
    sem_init_util( &sem_sync, 1, 0 );

    sem_wait_util( sem );
    printf("Reading count\n");
    memcpy(&count, addr, sizeof(short));
    printf("Incrementing and writing the count: %d\n", count);
    count++;
    memcpy(addr, &count, sizeof(short));
    sem_post_util( sem );

    if( count == n_proc ){
        printf("%d unblocks all the processes\n", getpid());
        for( int i = 0 ; i<n_proc-1; ++i )
            sem_post_util( addr + sizeof(short) );
    }
    else{
        printf("%d pauses\n", getpid());
        sem_wait_util( &sem_sync );
    }

    printf("%d continues\n", getpid());
    sem_close( sem );
    sem_close( &sem_sync );
    munmap_util( addr, SIZE );
    shm_unlink( SHARED_MEM );
}

I am running it with ./a.out & ./a.out & ./a.out

This is the output

[70] 19882
[71] 19883
Reading count
Incrementing and writing the count: 0
19882 pauses
Reading count
Incrementing and writing the count: 1
19883 pauses
Reading count
Incrementing and writing the count: 2
19884 unblocks all the processes
19884 continues

As you can see only the last process continued and processes 19882 and 19883 didn't continue and hanged there waiting. What am I doing wrong?

I want the semaphore to be in a shared memory along with some other data inside there.

0

2 Answers 2

0

You didn't put up the source to util.h, but it seems you are acquiring the semaphore via sem_wait_util( &sem_sync );, but releasing it via sem_post_util( addr + sizeof(short) );.

I would have expected it to be released via sem_post_util(&sem_sync);

Sign up to request clarification or add additional context in comments.

Comments

0

Operations on copies of POSIX semaphores are undefined. You must post and wait on the very memory that was initialized by sem_init or sem_open.

So, the memcpy of your sem_sync, initialized in ordinary process memory, to shared memory won't make that memory a viable semaphore.

Instead, try something like this:

struct shared_items {
  sem_t sem;
  short count;
} *shmem;

....

*shmem = mmap(0, sizeof(*shared_bundle), ..., shm_opened_fd, 0);

if (i_am_the_first_to_open_this_shared_memory) {
  sem_init(&shmem->sem, 1, 0);
}

....

sem_post(&shmem->sem);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.