Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Совместное использование переменных в shared lib


Автор: z7ql 20.9.2013, 06:26
Имеем следующее:
  • В исходнике обьявлена статическая переменная
  • Из исходников собирается библиотека
  • Библиотека линкуется к нескольким параллельным процессам
  • Целевая система RedHat, после планируется портировать на OpenVMS
Собственно вопрос:
От чего зависит будет ли обьявленная в shared библиотеке переменная физически одним местом в памяти для всех процессов или нет?

Небольшой пример кода:
Исходники библиотеки:

pool.h:
Код

#ifndef _ESF_POOL_H_
#define _ESF_POOL_H_

long unsigned int getId();

#endif


pool.c:
Код

#include "pool.h"

static long unsigned int id = 0;

long unsigned int getId()
{
  ++id;
  return id;
}


Исходник программы:
Код

int main(int argc, char * argv[])
{
  int i,val;

  for(i = 0; i < 20; ++i)
    printf("i am %s id %lu\n", argv[1], getId());
}


Сборка:
cc -c -fPIC pool.c
cc -shared -fPIC -rdynamic pool.o -o libpool.so
rm pool.o
cc main.c -rdynamic -lpool -L.

Результат:
То есть ожидалось, что при линковке система подключит переменную id к области памяти каждого из процессов - то есть она будет разделяемой памятью, как здесь http://stackoverflow.com/questions/10098489/sharing-executable-memory-pages-in-linux

На самом деле при запуске ./a.out 1 & ./a.out 2 получаем следующее:
Код

i am 2 id 1
i am 2 id 2
i am 2 id 3
i am 2 id 4
i am 2 id 5
i am 2 id 6
i am 2 id 7
i am 1 id 1
i am 1 id 2
i am 1 id 3
i am 1 id 4
i am 1 id 5
i am 1 id 6
i am 1 id 7
i am 1 id 8
i am 1 id 9
i am 1 id 10
i am 1 id 11
i am 1 id 12
i am 1 id 13
i am 1 id 14
i am 1 id 15
i am 1 id 16
i am 1 id 17
i am 1 id 18
i am 1 id 19
i am 1 id 20
i am 2 id 8
i am 2 id 9
i am 2 id 10
i am 2 id 11
i am 2 id 12
i am 2 id 13
i am 2 id 14
i am 2 id 15
i am 2 id 16
i am 2 id 17
i am 2 id 18
i am 2 id 19
i am 2 id 20

То есть создаётся по экземпляру переменной для каждой программы, с которой линкуется библиотека.
Итак. Можно ли при помощи сильного колдунства сделать id общей? Или надёжнее использовать mmap/shmget? 

Автор: xvr 20.9.2013, 12:40
Цитата(z7ql @  20.9.2013,  06:26 Найти цитируемый пост)
То есть ожидалось, что при линковке система подключит переменную id к области памяти каждого из процессов - то есть она будет разделяемой памятью, как здесь Ссылка

Не будет. В статье по ссылке обсуждается проблема экономии физической памяти, путем мэпирования одной и той же физической памяти (от библиотек) в каждый процесс. Это действительно делается, но писать в эту память не получится  smile Сегменты исполняемого кода мэпятся вообще без прав на запись, а сегменты данных - в приватном режиме (в режиме COPY-ON-WRITE)
Для организации разделяемых переменных между разными процессами их придется организовывать самому  smile 

Цитата(z7ql @  20.9.2013,  06:26 Найти цитируемый пост)
Или надёжнее использовать mmap/shmget?

Именно так

Автор: z7ql 26.9.2013, 14:12
Понял. Спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)