0

我正在使用 shm_open、ftruncate 和 mmap 在共享内存中存储一​​个动态创建的二维数组。当我对数组进行更新时,更新仅在进行该更新的进程中可见,而没有其他进程使用该共享内存映射。事不宜迟——代码(相关位):

int fd;
int** graph;
fd = shm_open("/graph", O_RDWR|O_CREAT, 0666);
ftruncate(fd, sizeof(int)*numVertices*numVertices);
graph = (int**) mmap(NULL, sizeof(int)*numVertices*numVertices, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
foo(numVertices, fd);

/* Down to function definition */
void foo(int numVertices, int fd) {
    int i=0;
    for (i; i<num_processes; i++) {
        int pid = fork();
        if (pid == 0) {
            int **graph = (int**) mmap(NULL, sizeof(int)*numVertices*numVertices, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
            graph_algorithm(i, numVertices, graph);
        }
    } 
}

void graph_algorithm(int proc_num, int numVertices, int** graph) {
     pthread_mutex_lock(&mutex);
     if (proc_num == 0) {
          graph[0][0] = 1;
     }
     pthread_mutex_unlock(&mutex);

     printf("Process %d: %d\n", proc_num, graph[0][0]);
}

当在 graph_algorithm 中完成打印时,proc_num 为 0 的进程在 graph[0][0] 处为 1,但所有其他进程都保持旧值 0。我省略了 fork 和 mmap 的错误检查——但这就是要点的问题。我还尝试在 graph[0][0] = 1 之后调用 msync(graph, sizeof(int)*numVertices*numVertices, MS_SYNC) 但无济于事。这是我第一次使用共享内存,我不知道我做错了什么。就我所见,这里或任何其他网站都没有出现这个问题。任何帮助是极大的赞赏。

4

2 回答 2

3

我怀疑问题是您使用了双指针,特别是考虑到您没有指定graph_algorithm()尺寸graph是什么。在这种情况下,graph[0][0]将等同于*(*graph),它可能指向映射内存,也可能不指向映射内存。您需要确保您的数组指向映射内存的单个连续区域。只要您知道至少一个维度,您仍然可以获得二维数组。因此,graph[x][y]您将使用graph[x * numVertices + y]. 根据您的编译器,您可能仍然可以使用双精度数组,但您需要显式提供graph. 所以你的原型graph_algorithm会变成类似

void graph_algorithm(int proc_num, int numVertices, int graph[][numVertices])
于 2013-02-19T05:23:24.687 回答
1

您的互斥体显然存在问题。除非互斥锁在进程之间共享,否则它不会阻止进程之间的并发访问。我什至没有看到它的定义或初始化。

还有一场比赛。即使互斥锁是共享的,任何其他进程中的 printf 也不能保证在进程 0 之前之后。

在访问结果之前,您应该有一种在图形算法结束时进行同步的方法,以确保所有操作都已完成。

二维数组没有问题,只要进程都同意尺寸。

于 2016-06-15T19:47:50.487 回答