有没有人知道任何可行的方法来模拟慢速DVD驱动器,例如在挂载的DMG/ISO映像上?
目标是针对慢速驱动器进行编程,因此需要模拟。任何想法将非常感激!
Update:同样,目标是模拟一个缓慢的I/O进程。不幸的是,像Network conditioning或Charles这样的工具并不能提供解决方案。涓涓细流已经过时了,没有更积极的发展:(
使用hdiutil,您可以在特制的HTTP服务器上挂载磁盘映像,但是您不能控制操作系统缓存,并且I/O速度不会是细粒度的。我建议两个非网络解决方案。
在I/O系统调用中插入慢速
您可以执行慢速I/O系统调用,例如通过DYLD_INSERT_LIBRARIES
。这种方法非常简单,这是我首先要尝试的方法。
您只需创建一个具有read(2)
和pread(2)
实现的库,如:
/* slow.c */
#define SLEEP_TIMESPEC {0, 25000000} // 25ms
ssize_t
read(int fildes, void *buf, size_t nbyte) {
struct timespec s = SLEEP_TIMESPEC;
(void) nanosleep(&s, NULL);
return (ssize_t) syscall(SYS_read, fildes, buf, nbyte);
}
ssize_t
pread(int d, void *buf, size_t nbyte, off_t offset) {
struct timespec s = SLEEP_TIMESPEC;
(void) nanosleep(&s, NULL);
return (ssize_t) syscall(SYS_pread, d, buf, nbyte, offset);
}
您可能还需要实现readv(2)
。您只需要将此C代码编译为共享库,并在运行程序之前设置DYLD_INSERT_LIBRARIES
来加载该库。您可能还需要定义DYLD_FORCE_FLAT_NAMESPACE
。参见dyld(1)
.
clang -arch i386 -arch x86_64 -shared -Wall slow.c -o slow.dylib
(该库是通用编译的,因为我在磁盘上的AIR应用程序实际上是i386,而不是x86_64)。
要测试库,只需执行:env DYLD_INSERT_LIBRARIES=slow.dylib DYLD_FORCE_FLAT_NAMESPACE=1 cat slow.c
您可能想要尝试cat
的值高于25ms,例如1秒,可以内联为{1, 0}
。同样,您应该从命令行启动应用程序:
env DYLD_INSERT_LIBRARIES=slow.dylib DYLD_FORCE_FLAT_NAMESPACE=1 path/to/YourApp.app/Contents/MacOS/YourApp
这会减慢每次读调用的速度(即使是通过高级api)。但是,一些读操作不会受到影响(例如mmap(2)
),并且您可能希望减慢某些文件的I/o,而不是其他文件的I/o。后一种情况可以通过捕获open(2)
来处理,但需要更多的工作。
每次读访问25ms足以使任何AIR应用程序明显变慢。当然,您应该根据需要调整此值。
使用较慢的文件系统
或者,您可以实现一个Fuse插件。如果从LoopbackFS (C或ObjC)开始,这尤其容易。
实际上,您可以很容易地在readFileAtPath:userData:buffer:size:offset:error:
方法或loopback_read
函数中调用nanosleep(2)
。
嗯,第一代DVD驱动器和播放器的读写速度为1350 kB/s(或1,32 MB/s);这个速度通常被称为"1x",是你能在任何DVD驱动器中找到的最慢的速度。
USB 1.1闪存驱动器的标称速度为12Mbps或1.5 mb/s,实际速度非常接近1x DVD驱动器。
那么你为什么不把你的图像复制到一个旧的USB 1.1闪存驱动器上,然后从那里挂载它呢?如果你没有,你可以在eBay上找到二手的。
我还应该提到宽带互联网连接,如ADSL2或HSPA (3.5G)的实际下载速度约为12Mbps,这是你想要的。