Пример

Пример

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

Листинг 13.5. Разделяемая память может начинаться с разных адресов в разных процессах

//pxshm/test3.c

1  #include "unpipc.h"

2  int

3  main(int argc, char **argv)

4  {

5   int fd1, fd2, *ptr1, *ptr2;

6   pid_t childpid;

7   struct stat stat;

8   if (argc != 2)

9    err_quit("usage: test3 <name>");

10  shm_unlink(Px_ipc_name(argv[1]));

11  fd1 = Shm_open(Px_ipc_name(argv[1]), O_RDWR | O_CREAT | O_EXCL, FILE_MODE);

12  Ftruncate(fd1, sizeof(int));

13  fd2 = Open("/etc/motd", O_RDONLY);

14  Fstat(fd2, &stat);

15  if ((childpid = Fork()) == 0) {

16   /* дочерний процесс */

17   ptr2 = Mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd2, 0);

18   ptr1 = Mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,

19    MAP_SHARED, fd1, 0);

20   printf("child: shm ptr = %p, motd ptr = %p ", ptr1, ptr2);

21   sleep(5);

22   printf("shared memory integer = %d ", *ptr1);

23   exit(0);

24  }

25  /* родительский процесс: вызовы map следуют в обратном порядке */

26  ptr1 = Mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);

27  ptr2 = Mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd2, 0);

28  printf("parent: shm ptr = %p, motd ptr = %p ", ptr1, ptr2);

29  *ptr1 = 777;

30  Waitpid(childpid, NULL, 0);

31  exit(0);

32 }

10-14 Создаем сегмент разделяемой памяти с именем, принимаемым в качестве аргумента командной строки. Его размер устанавливается равным размеру целого. Затем открываем файл /etc/motd.

15-30 После вызова fork и родительский, и дочерний процессы вызывают mmap дважды, но в разном порядке. Каждый процесс выводит начальный адрес каждой из областей памяти. Затем дочерний процесс ждет 5 секунд, родительский процесс помещает значение 777 в область разделяемой памяти, после чего дочерний процесс считывает и выводит это значение.

Запустив эту программу, мы убедимся, что объект разделяемой памяти начинается с разных адресов в пространствах дочернего и родительского процессов:

solaris % test3 test3.data

parent: shm ptr = eee30000, motd ptr = eee20000

child: shm ptr = eee20000, motd ptr = eee30000

shared memory integer = 777

Несмотря на разницу в начальных адресах, родительский процесс успешно помещает значение 777 по адресу 0xeee30000, а дочерний процесс благополучно считывает его по адресу 0хеее20000. Указатели ptr1 в родительском и дочернем процессах указывают на одну и ту же область разделяемой памяти, хотя их значения в этих процессах различны.

Данный текст является ознакомительным фрагментом.