惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
I
InfoQ
The Register - Security
The Register - Security
L
LangChain Blog
H
Help Net Security
The GitHub Blog
The GitHub Blog
S
Schneier on Security
博客园 - 【当耐特】
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
H
Heimdal Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
雷峰网
雷峰网
N
Netflix TechBlog - Medium
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - 聂微东
PCI Perspectives
PCI Perspectives
Last Week in AI
Last Week in AI
A
Arctic Wolf
宝玉的分享
宝玉的分享
T
The Blog of Author Tim Ferriss
S
Secure Thoughts
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
SecWiki News
SecWiki News
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
Schneier on Security
Schneier on Security
P
Proofpoint News Feed
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AI
AI
Engineering at Meta
Engineering at Meta

Whexy Blog

We lost the AIxCC. So, what now? Arm VMM with Apple's Hypervisor Framework Driving WaveShare E‐Paper Display with a Raspberry Pi Pico in MicroPython Use cgroup v2 inside docker containers Annual Hit Piece: Fuzzing Top Conference Paper Debunking Report Solving SSH Key Login Issues on Synology NAS Can SSD Cache Improve Synology NAS Write Speeds? Virtualization is all you need Running Windows Games on Mac Without Virtual Machines Tears of the Kingdom: End of an Era Anonymous CDN Traffic Relay Self-host Relay Service with CDN Home Networking Solution Building Your Own Blog System Connecting Smart Devices to SUSTech Campus Network Function Color Theory PMU Interrupts: How to handle them Asynchronous Mutex Using QEMU to run Linux images on M1 Macbook Alligator In Vest - My first research work Experience Using Several Plugins in Complex LaTeX Projects Variance in Rust Understanding Rust Generic Traits SUSTeam: Ultimate Gaming Platform Inline Assembly Language in C React Learning Notes Building a School Bus Schedule App for Apple Watch 12307 Train Ticket Purchase Platform Sakai and Local Folder Synchronization Building a Super Simple OpenJudge in Two Nights Setting Up Remote Backup for macOS Shell Script for Automatically Logging into SUSTech Campus Network Building a Movie Streaming System in the Dorm
Stop Forkin' Around: Faster Creating of Large Processes on Linux
Whexy · 2021-11-04 · via Whexy Blog

Whexy /

November 04, 2021

Forking is how a process in Linux is created. Even though the fork has been improved over the years to use the COW (copy-on-write) semantics, it still has to copy a certain amount of data from parent to child. Some students in the lab are working with a fuzzing machine, and they encounter some problems...

TL;DR

  • Use posix_spawn() to replace fork() if you want to launch a new program.
  • Use Pool to avoid time-consuming PT copying if you want to have multiple processes running simultaneously around a huge task.

Some students in the lab are working with a fuzzing machine. Fuzzing launches applications thousands of times with mutated input to see if a bug is triggered.

What bothered us is that launching the target application takes more and more time as the fuzzing goes. We sampled the program and found the most time-consuming part is the fork() system call. It turned out that the fuzzing process, collecting running information of every launch, grows larger and larger in the memory. When the process bloats to a certain level, cloning becomes a performance impact factor that we cannot ignore.

We know that fork() has been under optimization for decades. It now uses the COW (copy-on-write) semantics, which means no data in the user space would be copied until modified. But still, it has to copy a certain amount of data from parent to child.

We immediately thought that dynamic language interpreters face the same problem as we do. Along with the execution of the program, the interpreter process also experiences memory bloat. If they choose to create a new process, it can be pretty expensive. We investigated several solutions offered by Python in the face of multiprocess programs. Two of the most representative solutions are considered: pool and spawn.

Pool

The process pooling technique is a straightforward solution. It creates several empty processes at program initialization before the process grows too large and then assigns tasks to the processes for execution when needed. After the execution is finished, the processes are recycled to the pool to be used. 1

Limitation

  1. We must determine the number of concurrent processes required in advance. If I want to run 100 processes concurrently and find the pool only has five available, the program must stop and wait until running processes are freed and recycled.
  2. For processes that have been replaced with a brand new task by exec(), we cannot recycle it into the pool. That means we will lose the process forever.

Summary: Pooling techniques should be used for multitasking, especially for the initialization of multiprocess programs. However, it should not be used to launch other processes quickly.

Spawn

When launching other processes with exec(), we know that the copying in the fork() is unnecessary since the child process is immediately replaced with a new one. So what exactly does it copy? Well, the most prominent part is the page table. The page table is the part that Linux must copy to implement COW. It records whether the data in a particular memory address has been modified or not.

vfock()

The Berkeley version of Unix (BSD) introduced thevfork() system call in the early 1980s. vfork(2) does not copy the parent process to the child. Both processes share the parent's virtual address space; the parent is suspended until the child exits or calls exec() 2

🤔

posix_spawn()

On Linux, posix_spawn() is just implemented with fork() and exec(). It will use vfork() instead of fork() if it is safe. You can use posix_spawn(2) with the POSIX_SPAWN_USEVFORK flag to avoid the overhead of copying page tables when forking from a large process, while Linux can protect you from the deadlock we mentioned above.

This is the solution we finally adopted. It enables fast creation of new processes, avoids invalid copies of fork, and eliminates the need to create processes in advance, regardless of the pool size.

  1. Multi-processing in Python; Process vs Pool | by Nikhil Verma | Medium

  2. Minimizing Memory Usage for Creating Application Subprocesses (archive.org)

© LICENSED UNDER CC BY-NC-SA 4.0