С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/230: Рейтинг темы: голосов - 230, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 34

Работа с разделяемой памятью

30.11.2012, 21:01. Показов 43761. Ответов 13

Студворк — интернет-сервис помощи студентам
задание Написать две программы, осуществляющие взаимодействие через разделяемую память. Первая программа должна создавать сегмент разделяемой памяти и копировать туда свой собственный исходный текст, вторая программа должна брать оттуда этот текст, печатать его на экране и удалять сегмент разделяемой памяти из системы.
вот прога для записи
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
 
int main(){
int *ptr;
int md, fd, flag;
key_t key;
if((key = ftok("./key", 0)) < 0){
printf("Error of generate key\n");
exit(-1);
}
if((md = shmget(key, 8192*sizeof(int), 0777|IPC_CREAT|IPC_EXCL)) < 0){
if(errno != EEXIST){
printf("Error of create shared memory\n");
exit(-1);
}
else {
if((md = shmget(key, 8192*sizeof(int), 0)) < 0){
printf("Error of find shared memory\n");
exit(-1);
}
}
}
if((ptr = (int *)shmat(md, NULL, 0)) == (int *)(-1)){
printf("Error attach shared memory\n");
exit(-1);
}
int i;
i = 0;
fd = open ("./write.c", O_RDONLY);
while ((flag = read (fd, &ptr[i], 1)) > 0){
i++;
}
ptr[i+1]=EOF;
if (flag < 0){
printf ("Can not read file\n");
exit (1);
}
if(shmdt(ptr) < 0){
printf("Can't detach shared memory\n");
exit(-1);
}
printf("\nWriting of text this programm successfull\n\n");
return 0;
} вот для чтения 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
 
int main(){
int *ptr;
int md, flag;
key_t key;
int fd;
if((key = ftok("./key", 0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
if((md = shmget(key, 8192*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");
exit(-1);
}
if((ptr = (int *)shmat(md, NULL, 0)) == (int *)(-1)){
printf("Can't attach shared memory\n");
exit(-1);
}
int i;
i = 0;
printf("write.c:\n");
printf("-----------------------------------------------------------\n\n");
while (ptr[i] != EOF ){
putchar(ptr[i]);
++i;
}
if(shmctl(md, IPC_RMID, NULL) < 0){
printf("Can't free shared memory\n");
exit(-1);
}
printf("\nAll shared mamory released\n\n");
return 0;
}
запускаю по очереди и выводит какую то абракадабру
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.11.2012, 21:01
Ответы с готовыми решениями:

Работа с разделяемой памятью
Как записывать и считывать из памяти выделенной с помощью shm_open? shm_open(&quot;NAME&quot;, mode|O_RDWR, 0777)) а как дальше не знаю, и...

Работа с разделяемой памятью
вот задание Процесс 1 порождает потомка 2, они присоединяют к себе разделяемую память объемом (N*sizeof(int)). Процесс 1 пишет в нее...

Работа двух процессов с разделяемой памятью
Здравствуйте, срочно нужна помощь в работе с разделяемой памятью в UNIX. Первый процесс создает область разделяемой памяти и...

13
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
01.12.2012, 09:51
Цитата Сообщение от Rinat74 Посмотреть сообщение
запускаю по очереди и выводит какую то абракадабру
Если write.c это в _точности_ 1й файл, то идей что-то и нет, должно работать...
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
01.12.2012, 17:26
А зачем по-очереди запускаете?
Общая память на то и общая, что ее используют запущенные приложения для взаимодействия.

Полагаю, что система ПОДЧИСТИЛА всю использованную память, в том числе и shared-сегменты, когда приложение write отработало. Поэтому запуская read, вы ничего не получаете.

Не знаю, запустите их в потоке что ли, или одну из другой вызовите, но чтобы write и read были оба в запущенном состоянии, тогда по ключу должны получить один и тот же сегмент памяти.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
01.12.2012, 18:45
Цитата Сообщение от grgdvo Посмотреть сообщение
Полагаю, что система ПОДЧИСТИЛА всю использованную память, в том числе и shared-сегменты, когда приложение write отработало. Поэтому запуская read, вы ничего не получаете.
Откуда такая ересь?
1
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
05.12.2012, 16:50
Спасибо! Действительно, жестко протупил.
0
06.12.2012, 10:53

Не по теме:

Кстати, может в одном из соседних топиков о SHM, хотели услышать о persistence (как это св-во правильно обозвать по русски?) как главном достоинстве???

0
8 / 8 / 2
Регистрация: 16.03.2011
Сообщений: 257
30.09.2013, 20:18
Знаю что тема давно закрыта, но так получилось что я сегодня сдавал эту же лабу и мне задали вопрос по этой строчке кода:
C
1
if((md = shmget(key, 8192*sizeof(int), 0777|IPC_CREAT|IPC_EXCL)) < 0)
Почему именно 8192*sizeof(int) и для чего нужно 0777
Выручите плиз, завтра отчитываться(
0
40 / 37 / 15
Регистрация: 25.10.2012
Сообщений: 112
01.10.2013, 21:23
Цитата Сообщение от fenix117 Посмотреть сообщение
C
1
8192*sizeof(int)
Это запрашиваемый размер сегмента. Почему именно такой - Вам, очевидно, лучше знать.
Цитата Сообщение от fenix117 Посмотреть сообщение
C
1
0777
Это права на доступ к сегменту. 0777 означает, что владелец, группа и все остальные могут читать, записывать и исполнять содержимое сегмента.
1
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 8
07.06.2014, 21:00
Здравствуйте, подниму тему, так как срочно нужна помощь по аналогичной проблеме.
Первый процесс создает область разделяемой памяти и специализированный объект «семафор», после чего начинает принимать строки со стандартного ввода и записывать их в разделяемую память. Второй процесс должен корректно определить область данных разделяемой памяти и считать оттуда строки, записанные первым процессом.
Есть код:
Первый процесс:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#define key 5
int main(void)
{
 int semid,shmid;
struct sembuf sops;
char *shmaddr;
char str[256];
semid=semget(key,1,0666|IPC_CREAT); /* создаем один семафор с определенными правами доступа */
shmid=shmget(key,256,0666|IPC_CREAT); /*создаем разделяемую память на 256 элементов */
shmaddr=shmat(shmid,NULL,0); /* подключаемся к разделу памяти, в shmaddr -- указатель на буфер с разделяемой памятью*/
semctl(semid,0,IPC_SET, 0); /*инициализируем семафор со значением 0 */
sops.sem_num=0;
sops.sem_op=0;
 
/* запуск бесконечного цикла */
 
while(1) {printf(“Введите строку:);
if (gets(str)==NULL) break;
sops.sem_op=0; /* ожидание обнуления */
semop(semid,&sops,1); /* семафора */
strcpy(shmaddr,str); /* копируем строку в разд. память */
sops.sem_op=3; /* увеличение семафора на 3 */
semop(semid,&sops,1);
}
shmaddr[0]=’Q’; /* укажем 2ому процессу на то, */ 
sops.sem_op=3; /* что пора завершаться */
semop(semid,&sops,1);
sops.sem_op=0; /* ждем, пока обнулится семафор */
semop(semid,&sops,1);
shmdt(shmaddr); /* отключаемся от разд. памяти */
semctl(semid,0,IPC_RMID,0); /* убиваем семафор */
shmctl(shmid,IPC_RMID,NULL); /* уничтожаем разделяемую память */
exit(0);
}
Второй процесс:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* здесь нам надо корректно определить существование ресурса, если он есть -- подключиться, если нет -- сделать что-то еще, но как раз этого мы делать не будем*/
 
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#define key 75
 
int main(void)
{
int semid,shmid;
struct sembuf sops;
char *shmaddr;
char st=0;
 
/* далее аналогично предыдущему процессу -- инициализации ресурсов */
 
semid=semget(key,1,0666|IPC_CREAT); 
shmid=shmget(key,256,0666|IPC_CREAT); 
shmaddr=shmat(shmid,NULL,0); 
sops.sem_num=0;
sops.sem_op=0;
 
/* запускаем цикл */
 
while(st!=’Q’) {
 
printf(“Ждем открытия семафора\n”);
/* ожидание положительного значения семафора */
sops.sem_op=-2;
semop(semid,&sops,1);
/* будем ожидать, пока “значение семафора”+”значение sem_op” не перевалит за 0, то есть если придет “3”, то “3-2=1” */
 
/* теперь значение семафора равно 1 */
 
st=shmaddr[0];
 
{/*критическая секция -- работа с разделяемой памятью -- в этот момент первый процесс к разделяемой памяти доступа не имеет*/}
 
/*после работы -- закроем семафор*/
 
sops.sem_op=-1;
semop(semid,&sops,1);
 
/* вернувшись в начало цикла мы опять будем ждать, пока значение семафора не станет больше нуля */
}
shmdt(shmaddr); /* освобождаем разделяемую память и выходим */
exit(0);
}
Пытаюсь скомпилировать, выдает ошибку: warning: assignment makes pointer from integer without a cast
в строке : shmaddr=shmat(shmid,NULL,0);
Не могу понять, что не так. Помогите, пожалуйста, разобраться.
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
08.06.2014, 15:31
Почему key разные? Два процесса должны синхронизироваться "одинаковыми" объектами синхронизации.
0
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 8
09.06.2014, 08:32
Исправила ключи и избавилась от выдаваемой ошибки:
Процесс 1
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<string.h>
int main(void)
{key_t key;
int semid,shmid;
struct sembuf sops;
char *shmaddr;
char str[256];
key=ftok(/usr/mash/exmpl”,’S’); 
semid=semget(key,1,0666|IPC_CREAT); 
shmid=shmget(key,256,0666|IPC_CREAT); 
shmaddr=(char*)shmat(shmid,NULL,0); 
semctl(semid,0,IPC_SET, 0); 
sops.sem_num=0;
sops.sem_flg=0;
while(1) {printf(“Input string:);
if (fgets(str,255,stdin)==NULL) break;
sops.sem_op=0; 
semop(semid,&sops,1); 
strcpy(shmaddr,str); 
sops.sem_op=3; 
semop(semid,&sops,1);
}
shmaddr[0]=’Q’; 
sops.sem_op=3; 
semop(semid,&sops,1);
sops.sem_op=0; 
semop(semid,&sops,1);
shmdt(shmaddr); 
semctl(semid,0,IPC_RMID, 0); 
shmctl(shmid,IPC_RMID,NULL); 
exit(0);
}
Процесс 2
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<string.h>
 
int main(void)
{key_t key;
int semid,shmid;
struct sembuf sops;
char *shmaddr;
char st=0;
semid=semget(key,1,0666); 
shmid=shmget(key,256,0666); 
shmaddr=(char*)shmat(shmid,NULL,0); 
sops.sem_num=0;
sops.sem_flg=0;
 
while(st!=’Q’) {
printf(“Wait Open\n”);
sops.sem_op=-2;
semop(semid,&sops,1);
st=shmaddr[0];
while(1) {printf(“Read string:);
if (fgets(str,255,stdin)==NULL) break;
fputs(str, stdout);
}
sops.sem_op=-1;
semop(semid,&sops,1);
}
shmdt(shmaddr); /* освобождаем разделяемую память и выходим */
exit(0);
}
Теперь каждый процесс в отдельности компилируется, но не могу понять, как запустить оба процесса. Или их надо запускать поочереди?
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
12.06.2014, 05:28
Во-первых, добавьте в оба файла #include <sys/shm.h>
Не знаю, что она у вас компилирует, но явно не хватает.

Во-вторых, что-то вы переборщили с операциями над семафорами. Процесс 2 по сути зависим от процесса 1 и должен ждать от него некоего сигнала, что пора читать из буфера новые данные. Таким сигналом может быть процстое "дерганье" семафора в положительное значение. Не обязательно каждый раз синхронизировать процесс 1, так как он и так зависает в ожидании данных от пользователя.

Процесс 1

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
 
int main(int argc, char *argv[]) {
        key_t key;
        int semid, shmid;
        struct sembuf sops;
        char *shmaddr;
        char str[256];
 
        key=12345;
 
        if ((shmid = shmget(key, 256, IPC_CREAT | 0666)) < 0) { perror("shmget"); return 1; }
        if ((shmaddr = (char*)shmat(shmid, NULL, 0)) == (void*)-1) { perror("shmat"); return 1; }
 
        semid = semget(key, 1, IPC_CREAT | 0666);
        semctl(semid, 0, IPC_SET, 0);
        sops.sem_num = 0;
        sops.sem_flg = 0;
 
        do {
                // Вводим входную строку
                do {
                        printf("PROC#1> Input string (enter Q to exit):");
                } while (fgets(str, 255, stdin) == NULL);
                // Копируем данные в общую память
                strcpy(shmaddr, str);
                printf("PROC#1> String copied to the shared buffer\n");
                // Освобождаем доступ
                sops.sem_op = 1; 
                semop(semid, &sops, 1);
                printf("PROC#1> Access released to the shared buffer\n");
        } while (str[0] != 'Q');
        shmdt(shmaddr); 
        semctl(semid,0,IPC_RMID, 0); 
        shmctl(shmid,IPC_RMID,NULL); 
 
        return 0;
}
Процесс 2

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
 
int main(int argc, char *argv[]) {
        key_t key;
        int semid,shmid;
        struct sembuf sops;
        char *shmaddr, st = 0;
        char str[256];
 
        key=12345;
 
        if ((shmid = shmget(key, 256, 0666)) < 0) { perror("shmget"); return 1; }
        if ((shmaddr = (char*)shmat(shmid, NULL, 0)) == (void*)-1) { perror("shmat"); return 1; }
 
        semid = semget(key, 1, 0666);
        sops.sem_num = 0;
        sops.sem_flg = 0;
 
        do {
                // Ожидаем доступа к общей памяти
                printf("PROC#2> Waiting access to shared buffer\n");
                sops.sem_op = -1;
                semop(semid, &sops, 1);
                // Читаем строку
                strcpy(str, shmaddr);
                printf("PROC#2> String: %s\n", str);
        } while (str[0] != 'Q');
        shmdt(shmaddr);
 
        return 0;
}
1
0 / 0 / 0
Регистрация: 07.06.2014
Сообщений: 8
12.06.2014, 08:43
Спасибо. Но главный вопрос теперь, как запустить оба процесса. Или их надо запускать поочереди?
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
12.06.2014, 13:44
сначала 1, потом 2
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.06.2014, 13:44
Помогаю со студенческими работами здесь

Два процесса с разделяемой памятью
Нужно создать программу которая состоит из двух родственных процессов. второй из которых создает общую область памяти размером 12 байт по...

Написать скрипты для работы с разделяемой памятью и семаформаи
Здравствуйте! Нужна помощь по след заданию: Разработать программы для двух отдельных процессов, использующих общую память. В первой...

Организовать общение между двумя компьютерами с помощью нитей или разделяемой памятью
Организовать общение между двумя компьютерами с помощью нитей или разделяемой памятью. Имеются два кода, как правильно применить код и...

Работа с памятью на низком уровне
Здравствуйте. Нужен пример простой программы на C для записи и чтения 32разрядного слова в адрес памяти? Пример: нужно записать 32...

Метод прогонки с разделяемой памятью на CUDA
Здравствуйте. Есть метод прогонки на CUDA для глобальной памяти. Не могу реализовать то же самое для разделяемой ,пишет ошибки и всё. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru