d为何读写不一致
import std.stdio;
import core.sync.rwmutex : ReadWriteMutex;
enum PAGE_SIZE = 4096;
alias PageId = uint;
ubyte[] toBytes(uint value)
{
ubyte[] bytes = new ubyte[4];
bytes[0] = cast(ubyte)(value >> 24);
bytes[1] = cast(ubyte)(value >> 16);
bytes[2] = cast(ubyte)(value >> 8);
bytes[3] = cast(ubyte)(value);
return bytes;
}
class DiskManager
{
File dbFile;
__gshared ReadWriteMutex dbIOMutex;
shared static this()
{
this.dbIOMutex = new ReadWriteMutex(ReadWriteMutex.Policy.PREFER_WRITERS);
}
this(string dbFileName)
{
this.dbFile = File(dbFileName, "ab+");
}
void removeIfExists()
{
static import std.file;
if (std.file.exists(dbFile.name))
{
std.file.remove(dbFile.name);
}
}
void readPage(PageId pageId, out ubyte[PAGE_SIZE] pageData)
{
synchronized (dbIOMutex.reader)
{
dbFile.seek(pageId * PAGE_SIZE);
dbFile.rawRead(pageData);
}
}
void writePage(PageId pageId, ubyte[PAGE_SIZE] pageData)
{
synchronized (dbIOMutex.writer)
{
dbFile.seek(pageId * PAGE_SIZE);
dbFile.rawWrite(pageData);
}
}
}
void singleReadWrite()
{
// Scenario: 写并读回
DiskManager diskManager = new DiskManager("test.db");
diskManager.removeIfExists();
PageId pageId = 0;
ubyte[PAGE_SIZE] pageData = new ubyte[PAGE_SIZE];
pageData[0..4] = [1,2,3,4];
diskManager.writePage(pageId, pageData);
ubyte[PAGE_SIZE] readData = new ubyte[PAGE_SIZE];
diskManager.readPage(pageId, readData);
writeln("pageData[0..4] = ", pageData[0 .. 4]);
writeln("readData[0..4] = ", readData[0 .. 4]);
assert(pageData[0..4] == readData[0..4]);
}
void multiReadWrite()
{
// 场景: 成功读写相同位置
DiskManager diskManager = new DiskManager("test.db");
diskManager.removeIfExists();
PageId pageId = 0;
foreach (i; 0 .. 10)
{
ubyte[PAGE_SIZE] pageData = new ubyte[PAGE_SIZE];
pageData[0 .. 4] = toBytes(i);
diskManager.writePage(pageId, pageData);
ubyte[PAGE_SIZE] readData = new ubyte[PAGE_SIZE];
diskManager.readPage(pageId, readData);
writeln("pageData[0..4] = ", pageData[0 .. 4]);
writeln("readData[0..4] = ", readData[0 .. 4]);
assert(pageData[0] == readData[0]);
assert(pageData[1] == readData[1]);
assert(pageData[2] == readData[2]);
}
}
void main()
{
singleReadWrite();
writeln("~~~~~~");
multiReadWrite();
}
单次读写正常:
pageData[0..4] = [1, 2, 3, 4]
readData[0..4] = [1, 2, 3, 4]
放在for
循环,就出错了:
pageData[0..4] = [0, 0, 0, 0]
readData[0..4] = [0, 0, 0, 0]
pageData[0..4] = [0, 0, 0, 1]
readData[0..4] = [0, 0, 0, 0]
pageData[0..4] = [0, 0, 0, 2]
readData[0..4] = [0, 0, 0, 0]
pageData[0..4] = [0, 0, 0, 3]
readData[0..4] = [0, 0, 0, 0]
pageData[0..4] = [0, 0, 0, 4]
readData[0..4] = [0, 0, 0, 0]
// ...
可能,需要刷新
.
void writePage(PageId pageId, ubyte[PAGE_SIZE] pageData)
{
synchronized (dbIOMutex.writer)
{
dbFile.seek(pageId * PAGE_SIZE);
dbFile.rawWrite(pageData);
dbFile.flush();//加了这句.
dbFile.sync();
}
}
仍然有问题.
问题出在模式
上.
exists(dbFileName) ? "r+" : "w+"
这样,就可修复了.应重新实现FILE*
描述符.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现