Использование общей памяти в Posix Semaphore, ожидание и сигнал в C - PullRequest
2 голосов
/ 07 мая 2020

На примере приведенного ниже кода. Код останавливается после печати, ожидая остановки программы вручную, но не сигнализирует о следующей функции. Я проверил его несколько раз (даже удалив взаимное исключение) и обнаружил, что именно нахождение внутри for или while является причиной проблемы.

По словам других пользователей, я должен использовать разделяемую память , чтобы это работало, но я не знаю, как его использовать или применить к этому определенному коду c.

Я просмотрел множество веб-сайтов, чтобы лучше понять эту ситуацию, например https://www.geeksforgeeks.org/posix-shared-memory-api/

Наиболее рекомендуемые, которые я видел, - это shmget() и mmap().

Итак, вопрос, как я могу заставить sem_wait() работать внутри любого типа l oop с использованием общей памяти?

#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); 
}

1 Ответ

1 голос
/ 07 мая 2020

Итак, идея состоит в том, что вашему родительскому процессу потребуется создать новое пространство разделяемой памяти:

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

Тогда все процессы, которым требуется доступ к семафору, должны будут выполнить:

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

(Значит, вам нужно будет делать это в каждом дочернем процессе после вилки)

И тогда функции, использующие семафор, должны будут иметь доступ к указателю мьютекса (не забудьте добавить разыменование мьютекса).

После того, как они будут выполнены, каждый процесс, использующий мьютекс, должен будет выполнить:

shmdt(mutex);

Конечно, вы можете свободно хранить более сложные структуры в разделяемом память, пока вы выделяете достаточно места.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...