简体   繁体   中英

Using Shared memory in Posix Semaphore wait and signal in C

Using this code below as an example. The code stops after printing waiting until stop the program manually, but doesn't signal the next function. I checked it multiple times (even removing the mutual exclusion) and discovered that being inside the for or while is what causes the problem.

According to other users, I must use shared memory to get this working, but I don't know how to use it or apply it to this specific code.

I've looked at many websites to better understand this situation such as https://www.geeksforgeeks.org/posix-shared-memory-api/

The most recommended I've seen is shmget() and mmap() .

So the question, how can I get sem_wait() to work inside of any type of loop using Shared memory?

#include <stdio.h>
#include <semaphore.h> 
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
sem_t *mutex; 
void wait_t(int a)
{
    for (int i = 0; i < 3; i++)
    {
        if (a < 0)
        {
            sem_wait(&mutex);
            printf("waiting\n"); //Stops here due lack of shared memory
        }
        a--;
    }
}

void signal_t(int a)
{
    for (int i = 0; i < 3; i++)
    {
        if (a <= 0)
        {
            printf("signal\n");
            sem_post(&mutex);
        }
        a++;
    }
}

int main()
{ 
    int shared_mem_id = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT);
    mutex = shmat(shared_mem_id, NULL, 0);
    sem_init(&mutex, 1, 1);
    int i = -2;
    if(fork() == 0){ // create 1st child process
        mutex = shmat(shared_mem_id, NULL, 0);
        wait_t(i);
        exit(0);
        shmdt(mutex);
    }

    wait(NULL);
    if(fork() == 0){ // create 2nd child process
        mutex = shmat(shared_mem_id, NULL, 0);
        signal_t(i);
        exit(0);
        shmdt(mutex);
    }

    wait(NULL);
    if(fork() == 0){ // create 3nd child process
        mutex = shmat(shared_mem_id, NULL, 0);
        signal_t(i);
        exit(0);
        shmdt(mutex);
    }
    wait(NULL);
    printf("%d\n", i);
    exit(0); 
}

So, the idea is that your parent process would need to create a new shared memory space:

shared_mem_id = shmemget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT);

Then all the processes needing access to the semaphore will need to do:

sem_t *mutex = shmat(shared_mem_id, NULL, 0);

(So you'll need to do this in each child process, after the fork)

And then the functions that use the semaphore will need to have access to the mutex pointer (remember to add a dereference to mutex).

Once they are done, each process using the mutex will need to do:

shmdt(mutex);

Of course, you can feel free to store more complex structures in the shared memory as long as you allocate enough space.

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