如题所述,我该如何使用 mmap()
在堆中分配内存?这是我的唯一选择,因为 malloc()
不是可重入函数。
如题所述,我该如何使用 mmap()
在堆中分配内存?这是我的唯一选择,因为 malloc()
不是可重入函数。
malloc
还是mmap
都是线程安全的。根据POSIX标准,两者都不是异步信号安全的。实际上,mmap
在信号处理程序中可能工作得很好,但从信号处理程序分配内存的整个想法是非常糟糕的。mmap
来分配匿名内存,可以使用MAP_ANON
/MAP_ANONYMOUS
。p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
曾经这是不太可移植的,系统在支持拼写方式上有所不同,因此您应该编写预处理条件来使用任何一种可用的方式,但 POSIX 已经将这两种拼写方式作为标准采纳。
传统的、丑陋的版本来自很久以前,在 MAP_ANON
出现之前:
int fd = open("/dev/zero", O_RDWR);
p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
MAP_FAILED
而不是NULL
。SA_RESTART
标记的情况下中断系统调用很有用。将一个“什么都不做”的信号处理程序设置为中断系统调用,并使用pthread_kill
向特定线程发送信号是一种“自行制定”线程取消的方法,避免了pthread_cancel
带来的无法修复的资源泄漏问题。如果您设置一个计时器/闹钟以生成信号,则即使只有单个线程也可以很有用,以为系统调用设置超时时间。 - R.. GitHub STOP HELPING ICE/dev/zero
,而是使用shm_open
,它在内部执行大致相同的操作,但不需要您的文件系统拥有特殊文件。 - Jens Gustedtmunmap
函数,不能只传递0。 - R.. GitHub STOP HELPING ICEmmap
分配的块的开头存储大小,并返回指向存储大小后面一个字节的指针。然后释放该块就像备份以读取大小并将新指针和大小传递给munmap
一样简单。 - R.. GitHub STOP HELPING ICE
malloc()
不是可重入的,那么编写一个带锁的包装器比自己编写整个内存系统更容易些,但不改变原意。 - Carl Norum