我正在使用共享內存(shm_open/mmap)來跟蹤某些狀態。在我的共享內存我有結構:共享內存中的指針
typedef struct fim_t {
uint64_t num_procs;
uint64_t num_numa;
int64_t *numa_nodes[MAX_FIM_NUMA];
int64_t procs[MAX_FIM_PROC];
}fim_t;
我想要做的就是特效數組中加載進程ID,然後有numa_nodes陣列點特效數組值,所以我可以在一個地方操作的價值和它在所有參考文獻中都有變化。我的理解是設置numa_nodes引用procs數組的地址不應該是內存訪問衝突,因爲它們的地址都完全在共享內存段內。然而,當我嘗試訪問這個值時,我得到一個seg錯誤,這個值告訴我我以前的陳述必須是錯誤的。
下面是示例代碼:
int main(){
int fd;
int init_flag = 0;
if((fd = shm_open("fim", O_RDWR | O_CREAT | O_EXCL, S_IRWXU)) > 0){
printf("creating shared memory\n");
init_flag = 1;
} else {
printf("opening shared memory\n");
fd = shm_open("fim", O_RDWR, S_IRWXU);
}
if (-1 == fd) {
printf("fd is negative\n");
abort();
}
if ((1 == init_flag) && -1 == ftruncate(fd, sizeof(fim_t))){
printf("ftruncate failed %d\n", errno);
abort();
}
fim_t *fim = mmap(NULL, sizeof(fim_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(MAP_FAILED == fim){
printf("mmap failed\n");
abort();
}
if(init_flag){
fim->num_procs = 1;
my_rank = 0;
for(int x=0;x<MAX_FIM_PROC;x++){
fim->procs[x] = 0;
}
fim->numa_nodes[0] = &(fim->procs[0]);
} else {
my_rank = __sync_fetch_and_add(&(fim->num_procs),1);
fim->procs[my_rank] = my_rank;
fim->numa_nodes[0] = &(fim->procs[my_rank]);
}
printf("my rank is: %"PRId64"\n",my_rank);
sleep(5);
printf("my numa val is %"PRId64"\n",*fim->numa_nodes[0]);
printf("rank %"PRId64" is going down\n", my_rank);
// SHUTDOWN
uint64_t active = __sync_sub_and_fetch(&(fim->num_procs),1);
printf("num active is now %"PRId64"\n", active);
close(fd);
shm_unlink("fim");
return 0;
}
我希望/希望發生的將是我運行一個進程,然後立即開始另一個和第一處理打印「我的NUMA val爲1」是什麼(由於第二個進程設置numa_node [0]的值)並且都乾淨地退出。但是,第二個進程運行正常,但是在numa_node [0]的打印語句(睡眠之後)的第一個進程seg故障(內存訪問)。
所以這裏是我的問題:我做錯了什麼或者我的方法行不通?如果它不可行,是否有另一種方法來實現我期待的結果?
每個進程將有一個不同的共享內存地址。如果您在一個進程中設置指針,它們將不會在另一個進程中有效。 – Barmar