LINUXTALKS.CO

Gambas и C использование общей памяти.

 , , ,

L


0

2

В gambas есть функция Extern позволяющая делать вызовы функций из библиотек написанных на C. Я в C совсем не разбираюсь. Но знаю что в linux есть функция выделения общих страниц памяти. В gambas же такой функции нет, а она очень полезна, так как наверняка работала бы быстрее чем pipe и файлы в tmpfs.

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

Например хотелось бы получить значение типа pointer и прибавляя к нему смещения, использовать общее адресное пространство функциями https://gambaswiki.org/wiki/cat/externfunc

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

★★★★★★
Ответ на: комментарий от Meyer

Если будешь писать обёртку, то хотелось бы, что бы она принимала в качестве аргумента количество памяти, а возвращала бы какие то данные позволяющие другим процессам найти общую память. Например что бы эти данные можно было передать им через параметры запуска или переменную окружения. Читаю сейчас https://www.opennet.ru/docs/RUS/xtoolkit/x-1.html#x-1-7-3-3 и ничего толком не понимаю.

rezedent12    
★★★★★★
Windows / Firefox
Ответ на: комментарий от rezedent12

Тебе точно нужна shared memory? Или можно использовать POSIX mqueue?

Читаю сейчас https://www.opennet.ru/docs/RUS/xtoolkit/x-1.html#x-1-7-3-3 и ничего толком не понимаю.

shmget - это совсем древний сисколл из эпохи UNIX. В линуксе и *BSD он реализован, но лучше использовать shm_open + mmap.

В С это делается примерно так:

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

int main(int argc, char** argv)
{
    // Путь к файлу, который будем мапить. Ну ты знаешь, в юниксе подход "все есть файл" и все такое.
    const char* filename = "/tmp/shared_memory";

    // Открываем файл
    int fd = shm_open(filename, O_RDWR, S_IRUSR | S_IWUSR);

    // Будем мапить 2 МБ
    size_t shared_memory_size = 2 * 1024 * 1024;

    // Собственно, мапим "файл" в память
    void* shared_memory_ptr = mmap(NULL, shared_memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);


    /*
     * Обращаться к памяти можно по указателю shared_memory_ptr
     */

    // Поработали? Прибираем за собой. Но делать это нужно только из одной программы, работающей с этой памятью
    munmap(shared_memory_ptr, shared_memory_size);
    shm_unlink(filename);

    return 0;
}

Пример максимально простой и не отягощенный проверками на ошибки, которые могут возникнуть.

Meyer    
★★★★★★
Последнее исправление: Meyer (всего исправлений: 3)

Ubuntu / Firefox
Ответ на: комментарий от Meyer
void* shared_memory_ptr = mmap(NULL, shared_memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

Я так понял что этот код «создаёт» общую память. В другом процессе нужно выполнить этот же код? (Спрашиваю на всякий случай).

rezedent12    
★★★★★★
Последнее исправление: rezedent12 (всего исправлений: 1)

Windows / Firefox
Ответ на: комментарий от rezedent12

Я так понял что этот код «создаёт» общую память.

mmap просто отображает файл в память. Общую память «создает» сисколл shm_open и возвращает файловый дескриптор, который далее передается в mmap.

В другом процессе нужно выполнить этот же код? (Спрашиваю на всякий случай).

В другом процессе нужно вызвать shm_open и mmap. В основном процессе нужно вызвать munmap и shm_unlink при завершении.

Meyer    
★★★★★★
Ubuntu / Firefox