Я пытаюсь создать библиотеку ржавчины, чтобы упростить работу с общей памятью на Linux. Процессы смогут запросить общую память только через библиотеку, но я не могу гарантировать, что они не будут паниковать или быть внезапно убиты. Я намерен использовать библиотеку в запусках , в течение которой всегда есть хотя бы одна программа, использующая общую память, но как только run заключается в том, что общая память должна быть очищена. Нет никакой гарантии, что программа будет работать в течение всего run , и при этом не гарантированно, что последняя программа выхода выйдет чисто. Как лучше всего сохранить общую память, пока процессы все еще выполняются, но удалите ее сразу после того, как я понимаю, что последнее прикрепленное процесс выходит/
Насколько я понимаю, есть два варианта создания общей памяти на Linux: System V-стиль Shmat или Posix-Style Shm_open . Я предпочитаю shm_open , поскольку она создает общую память, доступную через файловую систему, но это не является строгим требованием.unsafe {
let shmid = shmget(KEY, SHMEM_SIZE, IPC_CREAT | IPC_EXCL | 0o770);
let shmaddr = shmat(shmid, null_mut(), 0);
shmctl(shmid, IPC_RMID, null_mut()); // mark it here for deletion
let ptr = shmaddr as *mut [u8; SHMEM_SIZE as usize];
*ptr = [12; SHMEM_SIZE as usize];
}
< /code>
и из другого процесса: < /p>
unsafe {
let shmid = shmget(KEY, SHMEM_SIZE, IPC_EXCL); // this will not work since KEY is already marked for deletion
let shmaddr = shmat(shmid, null_mut(), 0);
let ptr = shmaddr as *mut [u8; SHMEM_SIZE as usize];
*ptr = [13; SHMEM_SIZE as usize];
}
< /code>
тем самым откладывает делецию до тех пор, пока не выходит как новый, так и старый процесс. Демон хранит каждый PID внутри и получит дескриптор файла, вызывая pidfd_open syscall. Затем я мог бы использовать опрос , чтобы отслеживать, работают ли процессы, и удалить общую память, когда список PID становится пустым (см. Нижний колонтитул для моего полученного решения). Проблема с таким подходом заключается в том, что он чувствует себя хрупким, и я хотел бы избежать нереста отдельного процесса, чтобы отслеживать использование общей памяти. Программа EBPF будет поддерживать список PID, аналогичный первому подходу и удалить общую память, когда не останется процессов. Тем не менее, у меня мало опыта работы с EBPF, поэтому я не уверен, является ли это жизнеспособным подходом. Кроме того, EBPF обычно требует привилегированной среды, которой я бы предпочел избежать. pub fn handle_unix_socket(
&self,
pollfd: &mut PollFd,
) -> Result {
let mut buffer = [0; 4];
if pollfd
.revents()
.unwrap_or(PollFlags::empty())
.contains(PollFlags::POLLIN)
{
if let Ok((mut stream, _)) = self.listener.accept() {
let _ = stream.read(&mut buffer)?;
let pid = u32::from_be_bytes(buffer);
let fd = unsafe { syscall2(syscalls::Sysno::pidfd_open, pid as usize, 0).unwrap() };
let fd = unsafe { OwnedFd::from_raw_fd(fd as i32) };
stream.write_all(&buffer)?;
Ok((Some(fd), Some(pid)))
} else {
todo!()
}
} else {
Ok((None, None))
}
}
pub fn event_loop(&mut self) -> Result {
loop {
let mut pollfds = vec![PollFd::new(self.listener.as_fd(), PollFlags::POLLIN)];
for fd in self.fds.iter() {
pollfds.push(PollFd::new(fd.as_fd(), PollFlags::POLLIN));
}
poll(&mut pollfds, PollTimeout::NONE)?;
let (new_fd, new_pid) = self.handle_unix_socket(&mut pollfds[0])?;
let remove_indicies = (1..pollfds.len())
.rev()
.filter(|i| {
if let Some(pflag) = pollfds[*i].revents() {
if pflag.contains(PollFlags::POLLIN) {
return true;
}
}
false
})
.collect::();
for i in remove_indicies {
self.pids.remove(i - 1);
self.fds.remove(i - 1);
}
match (new_fd, new_pid) {
(Some(new_fd), Some(new_pid)) => {
self.fds.push(new_fd);
self.pids.push(new_pid);
}
_ => {}
}
if self.pids.is_empty() {
return Ok(());
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... p-on-linux
Лучший подход к управлению общей очисткой памяти на Linux? ⇐ Linux
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как сопоставить набор результатов JDBC с DTO: подход на основе перечислений и общий подход
Anonymous » » в форуме JAVA - 0 Ответы
- 34 Просмотры
-
Последнее сообщение Anonymous
-