Я пытаюсь создать библиотеку ржавчины, чтобы упростить работу с общей памятью на 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
-
Anonymous
1741819322
Anonymous
Я пытаюсь создать библиотеку ржавчины, чтобы упростить работу с общей памятью на Linux. Процессы смогут запросить общую память только через библиотеку, но я не могу гарантировать, что они не будут паниковать или быть внезапно убиты. Я намерен использовать библиотеку в [b] запусках [/b] , в течение которой всегда есть хотя бы одна программа, использующая общую память, но как только [b] run [/b] заключается в том, что общая память должна быть очищена. Нет никакой гарантии, что программа будет работать в течение всего [b] run [/b] , и при этом не гарантированно, что последняя программа выхода выйдет чисто. Как лучше всего сохранить общую память, пока процессы все еще выполняются, но удалите ее сразу после того, как я понимаю, что последнее прикрепленное процесс выходит/
Насколько я понимаю, есть два варианта создания общей памяти на 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(());
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79504993/best-approach-for-managing-shared-memory-cleanup-on-linux[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия