我被赋予了这个任务来实现一个带有以下定义的API,这些定义允许进程存储位于远程服务器上的文件的映射部分。我还需要实现客户端/服务器示例。
// Type definition for remote file location
struct fileloc {
struct in_addr ipaddress; // Remote IP
int port; // Remote port
char *pathname; // Remote file to be memory mapped
};
typedef struct fileloc fileloc_t;
// Create a new memory mapping in the virtual address space of the calling process
// location: Remote file to be memory mapped
void *rmmap(fileloc_t location, off_t offset);
// Deletes mapping for the specified address range
// addr: Address returned by mmap
int rmunmap(void *addr);
// Attempt to read up to count bytes from memory mapped area pointed
// to by addr + offset into buff
ssize_t mread(void *addr, off_t offset, void *buff, size_t count);
// Attempt to write up to count bytes to memory mapped area pointed
// to by addr + offset from buff
ssize_t mwrite(void *addr, off_t offset, void *buff, size_t count);
我正面临一些设计挑战。以下是我的想法:
rmmap()
,预定义服务器位置和请求的文件,以及偏移量。服务器将文件的固定块返回给客户端。unmap()
将用于"提交"更改服务器。 我仍然不确定锁定文件和解决冲突,但我是否走在正确的轨道上?
答案 0 :(得分:1)
我仍然不确定锁定文件和解决冲突
除了API之外,您还需要为传输定义一个协议,可能是内部协议(即,在库中实现,对用户不透明,TCP内部相对于{{1)实现的方式})。客户端需要维护持久连接并主动处理来自服务器的传入消息。这些消息将对应于其他连接客户端所做的写入 - 即,它们是对地图的更新。
当客户端A向服务器发送写入时,如果客户端B刚刚写入该位置并且客户端A未确认接收到有关此更新的更新,则会向客户端返回失败甲
您可以通过指示客户端无法写入尚未从服务器读取的位置来简化此操作,因此服务器只需要向已读取文件的任何部分的已连接客户端发送更新。
答案 1 :(得分:1)
任务是开放式的,因此许多可能的实现都是有效的。与您的选择相反的主要观点是,在真实环境中,人们想要mmap不适合系统内存的文件。如果我是老师,我会要求。因此,修改您的设计是为了工作:
锁定行为在问题中完全“定义不足”。简单的情况是每个客户端对每个文件都有一个独占锁,在mmaping时检索。一个不那么简单的案例会在读写时锁定块范围。锁定单个块很容易,并且可以作为从服务器读取和写入的结果来实现,但是每个读取和写入在整个块的范围内都不是原子的。请注意,未请求高级锁定。 API不足以声明独占锁或共享锁。