前面有了两篇讲解内存分配的博文:
持久性内存编程——事务性动态内存分配:https://blog.csdn.net/SweeNeil/article/details/90547136
持久性内存编程——原子分配动态内存:https://blog.csdn.net/SweeNeil/article/details/90444432
其实写得都有点简单,没有一个比较简单具体的案例,下面就把具体的内存分配的简单案例整理出来。
目录
一、事务性动态内存分配
二、原子性动态内存分配
rect_calc.c:
#include <stdio.h> #include <string.h> #include <libpmemobj.h> POBJ_LAYOUT_BEGIN(rect_calc); POBJ_LAYOUT_ROOT(rect_calc, struct my_root); POBJ_LAYOUT_TOID(rect_calc, struct rectangle); POBJ_LAYOUT_END(rect_calc); struct rectangle { int a; int b; }; struct my_root { TOID(struct rectangle) rect; }; int area_calc(const TOID(struct rectangle) rect) { return D_RO(rect)->a * D_RO(rect)->b; } int main(int argc, char *argv[]) { if (argc != 2) { printf("usage: %s file-name\n", argv[0]); return 1; } PMEMobjpool *pop = pmemobj_create(argv[1],POBJ_LAYOUT_NAME(rect_calc), PMEMOBJ_MIN_POOL, 0666); if (pop == NULL) { perror("pmemobj_create"); return 1; } TOID(struct my_root) root = POBJ_ROOT(pop, struct my_root); TX_BEGIN(pop) { TX_ADD(root); /* we are going to operate on the root object */ TOID(struct rectangle) rect = TX_NEW(struct rectangle); D_RW(rect)->a = 5; D_RW(rect)->b = 10; D_RW(root)->rect = rect; } TX_END int p = area_calc(D_RO(root)->rect); const TOID(struct rectangle) rects = D_RO(root)->rect; printf("%d\n", p); TX_BEGIN(pop) { TX_ADD(root); TX_FREE(D_RW(root)->rect); D_RW(root)->rect = TOID_NULL(struct rectangle); } TX_END }编译:
gcc rect_calc.c -o rect_calc -lpmemobj -lpmem -pthread运行:
sudo ./rect_calc /mnt/pmemdir/rect_calc 50感觉现在对于这个持久性内存编程还不够熟悉,编写起来不够灵活,对于layout的声明需要放在前面,不然编译可能会报错,当我把layout的声明放在了结构体之后,报出了如下问题:
测试在后面打印出 a与b的值使用了下面两种方式,都编译报错。
两种方式:
报错:
alloc.c:
#include <stdio.h> #include <string.h> #include <libpmemobj.h> POBJ_LAYOUT_BEGIN(rect_calc); POBJ_LAYOUT_ROOT(rect_calc, struct my_root); POBJ_LAYOUT_TOID(rect_calc, struct rectangle); POBJ_LAYOUT_END(rect_calc); struct rectangle { int a; int b; }; struct my_root { TOID(struct rectangle) rect; }; int rect_construct(PMEMobjpool *pop, void *ptr, void *arg) { struct rectangle *rect = ptr; rect->a = 5; rect->b = 10; pmemobj_persist(pop, rect, sizeof *rect); return 0; } int perimeter_calc(const TOID(struct rectangle) rect) { return D_RO(rect)->a * D_RO(rect)->b; } int main(int argc, char *argv[]) { if (argc != 2) { printf("usage: %s file-name\n", argv[0]); return 1; } PMEMobjpool *pop = pmemobj_create(argv[1],POBJ_LAYOUT_NAME(rect_calc), PMEMOBJ_MIN_POOL, 0666); if (pop == NULL) { perror("pmemobj_create"); return 1; } TOID(struct my_root) root = POBJ_ROOT(pop, struct my_root); POBJ_NEW(pop, &D_RW(root)->rect, struct rectangle, rect_construct, NULL); int p = perimeter_calc(D_RO(root)->rect); /* busy work */ printf("%d\n", p); POBJ_FREE(&D_RW(root)->rect); }编译:
gcc alloc.c -o alloc -lpmemobj -lpmem -pthread运行:
其实这两种方式的编程还是挺简单的,但是要用熟还是需要花点功夫。
参考:
http://pmem.io/2015/06/18/ntx-alloc.html