我需要在沙箱进程上运行不安全的本机代码,并且需要减少进程切换的瓶颈。两个进程(控制器和沙箱)共享两个自动重置events http://msdn.microsoft.com/en-us/library/windows/desktop/aa964766(v=vs.85).aspx以及用于通信的映射文件(共享内存)的连贯视图。
为了使本文更精简,我从示例代码中删除了初始化,但事件由控制器创建,使用 DuplicateHandle 进行复制,然后在工作之前发送到沙箱进程。
控制器来源:
void inSandbox(HANDLE hNewRequest, HANDLE hAnswer, volatile int *shared) {
int before = *shared;
for (int i = 0; i < 100000; ++i) {
// Notify sandbox of a new request and wait for answer.
SignalObjectAndWait(hNewRequest, hAnswer, INFINITE, FALSE);
}
assert(*shared == before + 100000);
}
void inProcess(volatile int *shared) {
int before = *shared;
for (int i = 0; i < 100000; ++i) {
newRequest(shared);
}
assert(*shared == before + 100000);
}
void newRequest(volatile int *shared) {
// In this test, the request only increments an int.
(*shared)++;
}
沙箱来源:
void sandboxLoop(HANDLE hNewRequest, HANDLE hAnswer, volatile int *shared) {
// Wait for the first request from controller.
assert(WaitForSingleObject(hNewRequest, INFINITE) == WAIT_OBJECT_0);
for(;;) {
// Perform request.
newRequest(shared);
// Notify controller and wait for next request.
SignalObjectAndWait(hAnswer, hNewRequest, INFINITE, FALSE);
}
}
void newRequest(volatile int *shared) {
// In this test, the request only increments an int.
(*shared)++;
}
测量:
-
inSandbox()
- 550ms,~350k 上下文切换,42% CPU(25% 内核,17% 用户)。
-
inProcess()
- 20ms,~2k 上下文切换,55% CPU(2% 内核,53% 用户)。
该机器是Windows 7 Pro、Core 2 Duo P9700、8GB内存。
一个有趣的事实是,沙箱解决方案使用了 42% 的 CPU,而进程内解决方案则使用了 55%。另一个值得注意的事实是,沙箱解决方案包含 350k 上下文切换,这比我们从源代码推断的 200k 上下文切换要多得多。
我需要知道是否有办法减少将控制权转移到另一个进程的开销。我已经尝试过使用管道而不是事件,结果更糟糕。我还尝试通过进行沙箱调用来根本不使用任何事件SuspendThread(GetCurrentThread())
并使控制器调用ResumeThread(hSandboxThread)
对每个请求,但性能与使用事件类似。
如果您有使用程序集(例如执行手动上下文切换)或 Windows 驱动程序工具包的解决方案,也请告诉我。我不介意必须安装驱动程序才能加快速度。
我听说Google Native Client做了类似的事情,但我只发现本文档 https://sites.google.com/a/chromium.org/dev/nativeclient/reference/anatomy-of-a-sys。如果您有更多信息,请告诉我。