网赌赢了钱被网站黑了需要怎么做,佛山伦教网站设计,灰色词快速排名接单,the 了wordpress内存映射文件#xff08;Memory-Mapped File#xff09;是⼀种将文件内容映射到内存中的机制#xff0c;允许程序直接访问文件数据#xff0c;就好像这些数据已经被加载到了内存⼀样。这个机制允许文件的内容被映射到⼀个进程的地址空间#xff0c;从而允许程序以⼀种更高…内存映射文件Memory-Mapped File是⼀种将文件内容映射到内存中的机制允许程序直接访问文件数据就好像这些数据已经被加载到了内存⼀样。这个机制允许文件的内容被映射到⼀个进程的地址空间从而允许程序以⼀种更高效的方式读取或写入文件数据同时多个进程可以映射同⼀个文件从而实现进程间的数据共享。这对于进程间通信非常有用。
mmap()
mmap() 是一个Unix和Linux系统调用用于在进程的地址空间中映射文件或设备或者创建匿名内存映射。它提供了一种在文件和进程的内存之间建立直接映射的机制。这意味着对于映射的内存区域的任何修改都将直接反映到底层的文件中反之亦然。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);以下是 mmap() 函数的基本参数和它们的描述 起始地址: 希望映射开始的内存地址。通常设置为 NULL让系统决定最佳起始地址。 长度: 要映射的文件或设备的字节数。 保护: 映射区域的访问权限。常见的权限包括 PROT_READ: 数据可以被读取。PROT_WRITE: 数据可以被写入。PROT_EXEC: 数据可以被执行。PROT_NONE: 数据不能被访问。 标志: 描述映射的类型和属性。常见的标志包括 MAP_SHARED: 更改会反映到底层文件或其他映射此文件的进程中。MAP_PRIVATE: 创建一个私有的映射更改不会写回底层文件。MAP_ANONYMOUS 或 MAP_ANON: 创建一个匿名映射不与任何文件关联。MAP_FIXED: 使用指定的起始地址如果该地址不可用映射会失败。 文件描述符: 要映射的文件或设备的描述符。如果使用 MAP_ANONYMOUS则此值可以设置为 -1。 偏移: 从文件或设备的哪个位置开始映射。通常这是以页面大小为单位的所以通常将偏移量设置为系统页面大小的倍数。
成功调用 mmap() 会返回新映射区域的地址。如果调用失败则返回 MAP_FAILED并在 errno 中设置一个错误代码。
几点注意事项
使用 mmap() 创建的映射应当在不再需要时使用 munmap() 释放。当映射文件时文件的长度应该大于或等于要映射的长度。可以使用 ftruncate() 调整文件大小。写入映射区域超出文件当前大小的部分可能会导致段错误。对于 MAP_SHARED 映射更改将写回底层文件但不一定立即写回。可以使用 msync() 来确保更改被同步到文件。
总的来说mmap() 是一种强大而灵活的机制用于文件I/O和进程间通信。
munmap()
munmap() 是一个Unix和POSIX系统调用用于取消映射一个之前通过 mmap() 映射到进程地址空间的内存区域。映射的内存区域可能是文件的映射、匿名内存或其他类型的内存对象。
当我们不再需要访问一个内存映射或当进程完成其操作并想释放资源时应该调用 munmap() 来取消映射。
以下是 munmap() 的基本参数和它们的描述 地址 (addr): 要取消映射的内存区域的起始地址。这应该是之前 mmap() 调用的返回值。 长度 (length): 要取消映射的内存区域的长度以字节为单位。
函数的基本原型如下
int munmap(void *addr, size_t length);返回值
成功时munmap() 返回 0。失败时返回 -1并设置全局变量 errno 以指示错误原因。
一些常见的使用场景和注意事项 资源管理: 在不需要访问映射内存区域时应及时使用 munmap() 释放资源。否则这可能会导致资源泄漏尤其是在长时间运行的程序中。 访问已取消映射的内存: 一旦使用 munmap() 取消映射了一个内存区域任何尝试访问该区域的操作都将导致未定义的行为通常是段错误 (segmentation fault)。 映射边界: 当取消映射一个内存区域时必须确保 addr 和 length 正确地对应于原始 mmap() 调用的值。尝试部分取消映射或使用不正确的地址和长度可能导致错误。 与其他资源的关联: 取消映射并不意味着与该映射相关的其他资源也被释放。例如如果映射了一个文件munmap() 只会取消映射但不会关闭文件。我们仍然需要使用 close() 系统调用来关闭文件。
总的来说munmap() 是内存映射管理的重要部分正确地使用它可以帮助避免资源泄漏和确保程序的稳定性。在设计使用内存映射的应用程序时我们应该始终确保在不再需要映射的时候调用 munmap() 来释放资源。
ftruncate()
ftruncate() 是一个系统调用用于调整/设置已打开的文件的大小。这个调用可以使文件变大或变小。当文件增大时新增的部分会被视为“空洞”并且会读取为零字节当文件缩小时超出指定长度的部分将被丢弃。
以下是 ftruncate() 的基本参数和它们的描述 文件描述符 (fd): 这是要调整大小的文件的文件描述符。通常这是使用 open() 或其他相关系统调用获得的。 长度 (length): 这是要设置的文件的新大小以字节为单位。
函数的基本原型如下
int ftruncate(int fd, off_t length);返回值
成功时ftruncate() 返回 0。失败时返回 -1并设置全局变量 errno 以指示错误原因。
一些常见的使用场景和注意事项 内存映射: 在使用 mmap() 创建文件的内存映射之前如果想映射的部分超过了文件的当前大小可以使用 ftruncate() 来增加文件的大小。 数据库和日志文件: 数据库系统或日志文件管理系统可能会预先分配大块的磁盘空间以提高效率而不是每次需要时都增加文件大小。这可以通过 ftruncate() 实现。 文件截断: 如果只想保留文件的前部分并删除其余部分ftruncate() 可以很容易地做到这一点。 空洞文件: 在某些文件系统上ftruncate() 可以用于创建所谓的“空洞文件”这是一个包含未初始化数据空洞的文件这些数据在磁盘上不占用任何空间但在读取时会返回零字节。
总的来说ftruncate() 是一个有用的系统调用尤其是在需要精细控制文件大小或预分配磁盘空间的应用中。
示例
在下面的例子中我们使用了两个 POSIX 信号量sem_parent和sem_child来控制两个进程之间的同步。父进程首先写入消息然后通过sem_post通知子进程。子进程在收到消息并处理完后通过sem_post通知父进程。这种方式确保了两个进程的同步并且避免了忙等待。
#include stdio.h
#include fcntl.h
#include sys/mman.h
#include unistd.h
#include string.h
#include sys/wait.h
#include semaphore.h#define FILE_PATH shared_memory_file
#define FILE_SIZE 1024
#define SEM_PARENT /sem_parent
#define SEM_CHILD /sem_childint main() {int fd;char *shared_mem;// Create a filefd open(FILE_PATH, O_RDWR | O_CREAT, 0777);if (fd -1) {perror(open);return 1;}// Set the file sizeftruncate(fd, FILE_SIZE);// Map the file into memoryshared_mem (char *)mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (shared_mem MAP_FAILED) {perror(mmap);return 1;}// Create semaphoressem_t *sem_parent sem_open(SEM_PARENT, O_CREAT, 0666, 0);sem_t *sem_child sem_open(SEM_CHILD, O_CREAT, 0666, 0);pid_t pid fork();if (pid 0) { // Childsem_wait(sem_parent); // Wait for parent signalprintf([Child] Received: %s\n, shared_mem);// Reply to the parentstrcpy(shared_mem, Message received by child!);printf([Child] Replied to parent.\n);sem_post(sem_child); // Signal the parent} else if (pid 0) { // Parentstrcpy(shared_mem, Hello from parent!);sem_post(sem_parent); // Signal the child// Wait for child signalsem_wait(sem_child);printf([Parent] Message from child: %s\n, shared_mem);wait(NULL); // Wait for child to finish} else {perror(fork);return 1;}// Cleanupmunmap(shared_mem, FILE_SIZE);close(fd);unlink(FILE_PATH);sem_close(sem_parent);sem_close(sem_child);sem_unlink(SEM_PARENT);sem_unlink(SEM_CHILD);return 0;
}
程序运行结果如下
majntiger:~/C_Project/mmap_project$ ./mmap_demo
[Child] Received: Hello from parent!
[Child] Replied to parent.
[Parent] Message from child: Message received by child!对于超出映射区域的内存访问结果是不确定的通常会导致错误。
当尝试访问超出我们通过mmap分配的映射区域的内存地址时实际上是在访问进程地址空间中的非法地址。这通常会产生一个SIGSEGV信号该信号表示段违规错误即“segmentation fault”。
简而言之 试图读取超出文件长度但在映射区域内的地址通常会读到0这是因为文件被视为以0字节填充直到映射的大小。 试图访问超出映射区域的地址通常会导致段违规错误segmentation fault。
因此最好确保只访问映射的内存区域内的地址避免超出这个范围以防止未定义的行为和潜在的程序崩溃。