У меня есть сегмент общей памяти Linux System V IPC, который заполняется одним процессом и читается многими другими. Все процессы используют интерфейс к сегменту разделяемой памяти в форме класса, который заботится о поиске, присоединении и отсоединении сегмента как части своих методов конструктора/деструктора.
Проблема здесь в том, что время от времени я вижу, что сегмент «раскололся». Я имею в виду, что глядя на вывод "ipcs -m -s", я вижу, что у меня есть два перечисленных сегмента: один, который был помечен для уничтожения, но к нему все еще подключены некоторые процессы, и второй, который, как представляется, получить все новые попытки присоединения к сегменту. Однако на самом деле я никогда не прошу ядро уничтожить сегмент. Что тут происходит?!
Еще одна вещь, которую следует отметить, это то, что, к сожалению, система, на которой это работает, серьезно перегружена в отделе памяти. Существует 1 ГБ физической памяти, без подкачки, а Committed_AS в /proc/meminfo сообщает о 2,5 ГБ выделенной памяти. К счастью, системные процессы на самом деле не используют так много памяти ... они просто просят ее (у меня все еще есть около 660 МБ «свободной» памяти, как сообщает vmstat). Хотя я знаю, что это далеко от идеала, в настоящее время я ничего не могу сделать с чрезмерно выделенной памятью. Однако, просматривая исходный код ядра/libc, я не вижу там ничего, что могло бы пометить сегмент общей памяти для удаления по какой-либо причине, кроме запроса пользователя (но, возможно, я где-то пропустил это, спрятанное там).
Для справки здесь конструктор класса интерфейса общей памяти:
const char* shm_ftok_pathname = "/usr/bin";
int shm_ftok_proj_id = 21;
// creates a key from a file path so different processes will get same key
key_t m_shm_key = ftok(shm_ftok_pathname, shm_ftok_proj_id);
if ( m_shm_key == -1 )
{
fprintf(stderr,"Couldn't get the key for the shared memory\n%s\n",strerror(errno));
exit ( status );
}
m_shm_id = shmget(m_shm_key, sizeof(shm_data_s), (IPC_CREAT | 0666));
if (m_shm_id < 0)
{
fprintf(stderr,"Couldn't get the shared memory ID\nerrno = %s \n",strerror(errno));
exit ( status );
}
// get a ptr to shared memory, which is a shared mem struct
// second arg of 0 says let OS choose shm address
m_shm_data_ptr = (shm_data_s *)shmat(m_shm_id, 0, 0);
if ( (int)m_shm_data_ptr == -1 )
{
fprintf(stderr,"Couldn't get the shared memory pointer\n");
exit ( status );
}
А вот мой вывод uname: Linux 2.6.18-5-686 #1 SMP Пт, 1 июня 00:47:00 UTC 2007 i686 GNU/Linux