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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
| //server.c
#include<stdio.h>/*
заголовочный файл стандартной библиотеки языка Си, содержащий определения макросов,
константы и объявления функций и типов, используемых для различных операций стандартного
ввода и вывода.*/
#include<stdlib.h>/*
заголовочный файл стандартной библиотеки языка Си, который содержит в себе функции,
занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования
типов и другие. Заголовок вполне совместим с C++ и известен в нём как cstdlib. Название
«stdlib» расшифровывается как «standard library» (стандартная библиотека).*/
#include<unistd.h>/*
Включаемый файл <unistd.h> содержит символические константы и структуры, которые еще не
были описаны в каких-либо других включаемых файлах.
-- Символические константы для доступа к файлам
-- Символические константы для позиционирования в файле
-- Маршрутные имена*/
#include<sys/types.h>//различные типы данных
#include<sys/ipc.h> //interprocess communication access structure
#include<sys/shm.h> //shared memory facility
#include<sys/sem.h>
#include<errno.h>/*заголовочный файл стандартной библиотеки языка программирования С[1],
содержащий объявление макроса для идентификации ошибок через их код. POSIX-совместимые
операционные системы, наподобие Unix и Linux, могут включать другие макросы для
определения ошибок через собственные коды errno. Значение errno имеет смысл только тогда,
когда системный вызов или функция возвращает признак ошибки.*/
#include<string.h>
#include"shmem.h"
int main()
{
key_t key; // тут хранить будем ключ сервера
Message *ptr; // указатель на структуру в которой храниться сегмент памяти и буфер
int shmid, semid;
FILE *strm;
strm=fopen("s-c.txt","w"); // отрываем файл s-c.txt для записи
key=ftok("server.c",'A');/*
The ftok() function returns a key based on path and id that is usable in subsequent calls to msgget(),
semget() and shmget(). The path argument must be the pathname of an existing file that the process is
able to stat().
The ftok() function will return the same key value for all paths that name the same file, when called
with the same id value, and will return different key values when called with different id values or with
paths that name different files existing on the same file system at the same time. It is unspecified whether
ftok() returns the same key value when called again after the file named by path is removed and recreated with
the same name.
Only the low order 8-bits of id are significant. The behaviour of ftok() is unspecified if these bits are 0.
Upon successful completion, ftok() returns a key. Otherwise, ftok() returns (key_t)-1 and sets errno to
indicate the error. */
if(key<0)
{
fprintf(strm,"\n Server: Невозможно получить ключ\n Ошибка №%d - %s\n", errno, strerror(errno));
/* Строковая функция strerror - функция языков C/C++,
транслирующая код ошибки, который обычно хранится в
глобальной переменной errno*/
exit(1);
}
fprintf(strm," Server: Ключ=%d", (int) key);
shmid=shmget(key,sizeof(Message),IPC_CREAT|IPC_EXCL|PERM);/*
The shmget() function returns the shared memory identifier associated with key. A shared memory identifier,
associated data structure and shared memory segment of at least size bytes, see <sys/shm.h>, are created
for key if one of the following is true:
The argument key is equal to IPC_PRIVATE.
The argument key does not already have a shared memory identifier associated with it and (shmflg&IPC_CREAT) is non-zero.
Upon creation, the data structure associated with the new shared memory identifier is initialised as follows:
The values of shm_perm.cuid, shm_perm.uid, shm_perm.cgid and shm_perm.gid are set equal to the effective user ID
and effective group ID, respectively, of the calling process.
The low-order nine bits of shm_perm.mode are set equal to the low-order nine bits of shmflg. The value of shm_segsz
is set equal to the value of size.
The values of shm_lpid, shm_nattch, shm_atime and shm_dtime are set equal to 0.
The value of shm_ctime is set equal to the current time.
When the shared memory segment is created, it will be initialised with all zero values.
RETURN VALUE
Upon successful completion, shmget() returns a non-negative integer, namely a shared memory identifier; otherwise,
it returns -1 and errno will be set to indicate the error. */
if (shmid<0)
{
fprintf(strm,"\n Server: Невозможно выделить сегмент разделяемой памяти\n Ошибка №%d - %s\n", errno, strerror(errno));
exit(1);
}
fprintf(strm,"\n Server: ID сегмента=%d", shmid);
ptr=(Message*)shmat(shmid,0,0);/*
The shmat() function operates on XSI shared memory (see the Base Definitions volume of IEEE Std 1003.1-2001, Section 3.340,
Shared Memory Object). It is unspecified whether this function interoperates with the realtime interprocess communication
facilities defined in Realtime.
The shmat() function attaches the shared memory segment associated with the shared memory identifier specified by shmid to the
address space of the calling process. The segment is attached at the address specified by one of the following criteria:
If shmaddr is a null pointer, the segment is attached at the first available address as selected by the system.
If shmaddr is not a null pointer and (shmflg &SHM_RND) is non-zero, the segment is attached at the address given
by (shmaddr -((uintptr_t)shmaddr %SHMLBA)). The character '%' is the C-language remainder operator.
If shmaddr is not a null pointer and (shmflg &SHM_RND) is 0, the segment is attached at the address given by shmaddr.
The segment is attached for reading if (shmflg &SHM_RDONLY) is non-zero and the calling process has read permission;
otherwise, if it is 0 and the calling process has read and write permission, the segment is attached for reading and writing.
RETURN VALUE
Upon successful completion, shmat() shall increment the value of shm_nattch in the data structure associated with the shared
memory ID of the attached shared memory segment and return the segment's start address.
Otherwise, the shared memory segment shall not be attached, shmat() shall return -1, and errno shall be set to indicate the error.*/
if (ptr<0)
{
fprintf(strm,"\n Server: Невозможно присоединить сегмент к адресному пространству процесса\n Ошибка №%d - %s\n", errno, strerror(errno));
exit(1);
}
fprintf(strm,"\n Server: Разделяемая память подключена по адресу %p",ptr);
semid=semget(key,2,IPC_CREAT|IPC_EXCL|PERM); /* Get semaphore. */
if (semid<0)
{
fprintf(strm,"\n Server: Невозможо создать группу семафоров\n Ошибка №%d - %s\n", errno, strerror(errno));
exit(1);
}
fprintf(strm,"\n Server: ID группы семафоров=%d",semid);
fclose(strm);
if (semop(semid, &proc_wait,1)<0) /* Operate on semaphore. */
{
strm=fopen("s-c.txt","a");
fprintf(strm,"\n Server: Невозможно выполнить операцию proc_wait\n Ошибка №%d - %s\n", errno, strerror(errno));
fclose(strm);
exit(1);
}
semop(semid,&mem_lock[0],2);
strm=fopen("s-c.txt","a");
fprintf(strm,"\n Server: Считана строка: %s\n\n", ptr->buff);
semop(semid,&mem_unlock,1);
shmdt(ptr);
fclose(strm);// close file
return 0;
} |