LINUXTALKS.CO

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

 , , ,

L


0

2

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

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

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

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

★★★★★★

Но знаю что в linux есть функция выделения общих страниц памяти.

Ты про POSIX Shared Memory? Я не знаю как его использовать из Gambas, но если ты говоришь что

В gambas есть функция Extern позволяющая делать вызовы функций из библиотек написанных на C

то можно сделать библиотеку-обертку над shm_open, mmap, shm_unlink на С с функциями типа init/shutdown и вызывать их из Gambas. Но это конечно лютый костыль.

Лучше найти способ вызывать эти функции напрямую.

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

Есть же еще POSIX Message Queues.

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

Но как их использовать в gambas, ещё менее понятно, точнее совсем не понятно.

rezedent12    
★★★★★★
Windows / Firefox
Ответ на: комментарий от 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