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 <stdbool.h>
- #include <memory.h>
- int main() {
- int *count; /* Указатель на разделяемую память */
- int shmid; /* IPC дескриптор для области разделяемой памяти */
- int semid;
- FILE *file;
- char pathname[20]; /* Имя файла,
- используемое для генерации ключа. Файл с таким
- именем должен существовать в текущей директории */
- key_t key; /* IPC ключ */
- char tmp[10];
- static struct sembuf sop_lock[2] = {
- 0, 0, 0, /* ожидать обнуления семафора */
- 0, 1, 0 /* затем увеличить значение семафора на 1 */
- };
- static struct sembuf sop_unlock[1] = {
- 0, -1, 0 /* обнулить значение семафора */
- };
- while (true) {
- printf("Enter \"open\", \"read\" or \"write\":\n");
- fflush(stdout);
- gets(tmp);
- if (strcmp(tmp, "open") == 0) {
- printf("Enter key-file name: \n");
- scanf("%s", pathname);
- file = fopen(pathname, "w+");
- fclose(file);
- /* Генерируем IPC ключ из имени файла в
- текущей директории и номера экземпляра области
- разделяемой памяти 0 */
- if ((key = ftok(pathname, 0)) < 0) {
- printf("Can\'t generate key\n");
- exit(-1);
- }
- if ((semid = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL)) < 0) {
- if (errno = EEXIST) {
- /* Действительно, ошибка вызвана существованием объекта */
- if ((semid = semget(key, 1, 0666)) < 0) return (-1); /* Возможно, не хватает системных ресурсов */
- }
- }
- /* Пытаемся эксклюзивно создать разделяемую память для
- сгенерированного ключа, т.е. если для этого ключа она
- уже существует, системный вызов вернет отрицательное
- значение. Размер памяти определяем как размер массива
- из трех целых переменных, права доступа 0666 – чтение
- и запись разрешены для всех */
- if ((shmid = shmget(key, sizeof(int),
- 0666 | IPC_CREAT | IPC_EXCL)) < 0) {
- /* В случае ошибки пытаемся определить: возникла ли она
- из-за того, что сегмент разделяемой памяти уже существует
- или по другой причине */
- if (errno != EEXIST) {
- /* Если по другой причине – прекращаем работу */
- printf("Can\'t create shared memory\n");
- exit(-1);
- } else {
- /* Если из-за того, что разделяемая память уже
- существует, то пытаемся получить ее IPC
- дескриптор и, в случае удачи, сбрасываем флаг
- необходимости инициализации элементов массива */
- printf("Shared memory alredy exists. Trying to open...\n");
- if ((shmid = shmget(key, sizeof(int), 0)) < 0) {
- printf("Can\'t find shared memory\n");
- exit(-1);
- }
- }
- }
- /* Пытаемся отобразить разделяемую память в адресное
- пространство текущего процесса. Обратите внимание на то,
- что для правильного сравнения мы явно преобразовываем
- значение -1 к указателю на целое.*/
- if ((count = (int *) shmat(shmid, NULL, 0)) == (int *) (-1)) {
- printf("Can't attach shared memory\n");
- exit(-1);
- } else printf("Success!\n");
- }
- if (strcmp(tmp, "read") == 0) {
- semop(semid, &sop_lock[0], 2);
- printf("Number of count is: %d \n", *count);
- semop(semid, &sop_unlock[0], 1);
- }
- if (strcmp(tmp, "write") == 0) {
- semop(semid, &sop_lock[0], 2);
- printf("Enter number to write: ");
- scanf("%d", count);
- semop(semid, &sop_unlock[0], 1);
- }
- if (strcmp(tmp, "exit") == 0) {
- if (shmdt(count) < 0) {
- printf("Can't detach shared memory\n");
- exit(-1);
- }
- return 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement