Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <sys/shm.h>
- #include <stdio.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <stdbool.h>
- int P(int semid, struct sembuf *buf) {
- buf->sem_op = -1;
- buf->sem_flg = 0;
- buf->sem_num = 0;
- return semop(semid, buf, 1);
- }
- int V(int semid, struct sembuf *buf) {
- buf->sem_op = 1;
- buf->sem_flg = 0;
- buf->sem_num = 0;
- return semop(semid, buf, 1);
- }
- void pause_sem()
- {
- for(int i=0; i<500000000L; i++);
- }
- int main() {
- int fd; /* Файловый дескриптор для файла, в котором будет храниться наша информация*/
- size_t length; /* Длина отображаемой части файла */
- int i;
- /* Ниже следует описание типа структуры, которыми мы забъем файл, и
- двух указателей на подобный тип. Указатель ptr будет использоваться в качестве
- начального адреса выделенной области памяти, а указатель tmpptr для перемещения
- внутри этой области. */
- struct A {
- int f;
- } *ptr, *tmpptr;
- /* Открываем файл с одновремееным его созданием (если такого файла не было).
- Права доступа к файлу при создании определяем как read-write для всех категорий
- пользователей (0666). Из-за ошибки в Linux, мы будем вынуждены ниже в системном вызове
- mmap() разрешить в отображении файла и чтение, и запись, хотя реально нам нужна только
- запись. Поэтому и при открытии файла мы вынуждены задавать O_RDWR. */
- fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);
- if( fd == -1){
- /* Если файл открыть не удалось, выдаем сообщение об ошибке и завершаем работу */
- printf("File open failed!\n");
- exit(1);
- }
- /* Вычисляем будущую длину файла (мы собираемся записать в него 1000 структур) */
- length = 3*sizeof(struct A);
- /* Отображаем файл в память. Разрешенные операции над отображением
- указываем как PROT_WRITE | PROT_READ по уже сказанным причинам. Значение
- флагов ставим в MAP_SHARED, так как мы хотим сохранить информацию, которую
- занесем в отображение, на диске. Файл отображаем с его начала (offset = 0) и до
- конца (length = длине файла). */
- ptr = (struct A *)mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
- /* Файловый дескриптор нам более не нужен, и мы его закрываем */
- close(fd);
- if( ptr == MAP_FAILED ){
- /* Если отобразить файл не удалось, сообщаем об ошибке и завершаем работу */
- printf("Mapping failed!\n");
- exit(2);
- }
- // для семафоров
- int semid;
- struct sembuf mybuf;
- int* array; /* указатель на массив из 3 интов.
- Буду туда передавать последовательно цифры и их получать */
- char pathname[] = "5mapped.dat";
- key_t key;
- if ((key = ftok(pathname, 0)) < 0) {
- printf("Can\'t generate key\n");
- exit(-1);
- }
- // получаю дескриптор для семафора
- if ((semid = semget(key, 1, 0666)) < 0) {
- printf("Semaphore not found. Trying to create...\n");
- if ((semid = semget(key, 1, 0666 | IPC_CREAT)) < 0) {
- printf("Can\'t get semid\n");
- exit(-1);
- }
- printf("Create successful!\n");
- tmpptr = ptr;
- // writing nums
- for (int i = 0; i < 3; ++i){
- printf("wrote %d number to mapped file\n", array[i]);
- tmpptr->f = 0;
- tmpptr++;
- }
- // Первый запуск
- V(semid, &mybuf);
- }
- // main prog loop
- for (int a = 0; a < 5; a++)
- {
- P(semid, &mybuf);
- tmpptr = ptr;
- // reading nums
- for (int i = 0; i < 3; ++i){
- array[i] = tmpptr->f;
- printf("read %d number from mapped file.\n", tmpptr->f);
- tmpptr++;
- }
- array[0] += 1;
- tmpptr = ptr;
- // writing nums
- for (int i = 0; i < 3; ++i){
- printf("wrote %d number to mapped file\n", array[i]);
- tmpptr->f = array[i];
- tmpptr++;
- }
- pause_sem();
- array[2] += 1;
- tmpptr = ptr;
- // writing nums
- for (int i = 0; i < 3; ++i){
- printf("wrote %d number to mapped file\n", array[i]);
- tmpptr->f = array[i];
- tmpptr++;
- }
- V(semid, &mybuf);
- printf("\nProgram 1 was spawn %d times, program 2 - %d times, total - %d times\n",
- array[0], array[1], array[2]);
- }
- /* Прекращаем отображать файл в память, записываем содержимое отображения
- на диск и освобождаем память. */
- if (munmap((void *)ptr, length) < 0)
- {
- printf("finished working here.");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement