Advertisement
Guest User

Untitled

a guest
May 27th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.01 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <sys/sem.h>
  4. #include <sys/shm.h>
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #include <stdlib.h>
  8. #include <dirent.h>
  9. #include <unistd.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <limits.h>
  13. #include <fcntl.h>
  14. #include <sys/mman.h>
  15. #include <stdbool.h>
  16.  
  17. int P(int semid, struct sembuf *buf) {
  18.     buf->sem_op = -1;
  19.     buf->sem_flg = 0;
  20.     buf->sem_num = 0;
  21.  
  22.     return semop(semid, buf, 1);
  23. }
  24.  
  25. int V(int semid, struct sembuf *buf) {
  26.     buf->sem_op = 1;
  27.     buf->sem_flg = 0;
  28.     buf->sem_num = 0;
  29.  
  30.     return semop(semid, buf, 1);
  31. }
  32.  
  33. void pause_sem()
  34. {
  35.     for(int i=0; i<500000000L; i++);
  36. }
  37.  
  38. int main() {
  39.     int fd; /* Файловый дескриптор для файла, в котором будет храниться наша информация*/
  40.     size_t length; /* Длина отображаемой части файла */
  41.     int i;
  42.  
  43.     /* Ниже следует описание типа структуры, которыми мы забъем файл, и
  44.      двух указателей на подобный тип. Указатель ptr будет использоваться в качестве
  45.      начального адреса выделенной области памяти, а указатель tmpptr для перемещения
  46.      внутри этой области. */
  47.     struct A {
  48.         int f;
  49.     } *ptr, *tmpptr;
  50.  
  51.     /* Открываем файл с одновремееным его созданием (если такого файла не было).
  52.     Права доступа к файлу при создании определяем как read-write для всех категорий
  53.     пользователей (0666). Из-за ошибки в Linux, мы будем вынуждены ниже в системном вызове
  54.     mmap() разрешить в отображении файла и чтение, и запись, хотя реально нам нужна только
  55.     запись. Поэтому и при открытии файла мы вынуждены задавать O_RDWR. */
  56.     fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);
  57.  
  58.     if( fd == -1){
  59.         /* Если файл открыть не удалось, выдаем сообщение об ошибке и завершаем работу */
  60.         printf("File open failed!\n");
  61.         exit(1);
  62.     }
  63.  
  64.     /* Вычисляем будущую длину файла (мы собираемся записать в него 1000 структур) */
  65.     length = 3*sizeof(struct A);
  66.  
  67.     /* Отображаем файл в память. Разрешенные операции над отображением
  68.     указываем как PROT_WRITE | PROT_READ по уже сказанным причинам. Значение
  69.     флагов ставим в MAP_SHARED, так как мы хотим сохранить информацию, которую
  70.     занесем в отображение, на диске. Файл отображаем с его начала (offset = 0) и до
  71.     конца (length = длине файла). */
  72.     ptr = (struct A *)mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
  73.  
  74.     /* Файловый дескриптор нам более не нужен, и мы его закрываем */
  75.     close(fd);
  76.  
  77.     if( ptr == MAP_FAILED ){
  78.         /* Если отобразить файл не удалось, сообщаем об ошибке и завершаем работу */
  79.         printf("Mapping failed!\n");
  80.         exit(2);
  81.     }
  82.  
  83.     // для семафоров
  84.     int semid;
  85.     struct sembuf mybuf;
  86.  
  87.     int* array; /* указатель на массив из 3 интов.
  88.                     Буду туда передавать последовательно цифры и их получать */
  89.     char pathname[] = "5mapped.dat";
  90.  
  91.     key_t key;
  92.  
  93.     if ((key = ftok(pathname, 0)) < 0) {
  94.         printf("Can\'t generate key\n");
  95.         exit(-1);
  96.     }
  97.  
  98.     // получаю дескриптор для семафора
  99.     if ((semid = semget(key, 1, 0666)) < 0) {
  100.         printf("Semaphore not found. Trying to create...\n");
  101.         if ((semid = semget(key, 1, 0666 | IPC_CREAT)) < 0) {
  102.             printf("Can\'t get semid\n");
  103.             exit(-1);
  104.         }
  105.         printf("Create successful!\n");
  106.  
  107.         tmpptr = ptr;
  108.         // writing nums
  109.         for (int i = 0; i < 3; ++i){
  110.             printf("wrote %d number to mapped file\n", array[i]);
  111.             tmpptr->f = 0;
  112.             tmpptr++;
  113.         }
  114.  
  115.         // Первый запуск
  116.         V(semid, &mybuf);
  117.     }
  118.  
  119.     // main prog loop
  120.     for (int a = 0; a < 5; a++)
  121.     {
  122.         P(semid, &mybuf);
  123.  
  124.         tmpptr = ptr;
  125.         // reading nums
  126.         for (int i = 0; i < 3; ++i){
  127.             array[i] = tmpptr->f;
  128.             printf("read %d number from mapped file.\n", tmpptr->f);
  129.             tmpptr++;
  130.         }
  131.  
  132.         array[0] += 1;
  133.  
  134.         tmpptr = ptr;
  135.         // writing nums
  136.         for (int i = 0; i < 3; ++i){
  137.             printf("wrote %d number to mapped file\n", array[i]);
  138.             tmpptr->f = array[i];
  139.             tmpptr++;
  140.         }
  141.  
  142.         pause_sem();
  143.         array[2] += 1;
  144.  
  145.         tmpptr = ptr;
  146.         // writing nums
  147.         for (int i = 0; i < 3; ++i){
  148.             printf("wrote %d number to mapped file\n", array[i]);
  149.             tmpptr->f = array[i];
  150.             tmpptr++;
  151.         }
  152.  
  153.         V(semid, &mybuf);
  154.  
  155.         printf("\nProgram 1 was spawn %d times, program 2 - %d times, total - %d times\n",
  156.                array[0], array[1], array[2]);
  157.     }
  158.    
  159.  
  160.     /* Прекращаем отображать файл в память, записываем содержимое отображения
  161.     на диск и освобождаем память. */
  162.     if (munmap((void *)ptr, length) < 0)
  163.     {
  164.         printf("finished working here.");
  165.     }
  166.  
  167.     return 0;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement