在共享内存中初始化1D或2D阵列

时间:2014-12-08 15:55:45

标签: c arrays linux posix shared-memory

我正在尝试将字符串的2D字符串数组初始化为POSIX共享内存,以便在其他3个进程之间共享。有很多关于如何使用指针在进程之间共享单个字符串或整数的教程,但我找不到有关如何使用mmap()初始化1D或2D数组的示例。我已经发布了我到目前为止的内容。它是第一个程序,它创建共享内存对象并使用值char files[20][2][100]初始化数组files[0][0][0] = '\0'

在C中初始化和共享数组的正确方法是什么?

对于上下文,我编写了这个项目的简单版本(在有用的S.O.大师的建议下),它不使用共享内存并将所有4个进程(由/**********/分隔)合并为一个。它在下面。

我在前一篇文章中提到了一个涉及结构的类似问题,但我需要使用多维数组代替我的项目。有关该答案的任何见解都会有所帮助HERE

感谢。

CODE SO FAR:(程序初始化共享内存对象和数组)

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main (int argc, char *argv[])
{
    char files [20][2][100]; 


    /* the size of shared memory object */
    int size = sizeof(files);

    /* name of the shared memory object */
    const char *name = "/PROJ4_SHARED_MEM";

    /* shared memory file descriptor */
    int shm_fd;

    /* pointer to shared memory obect */
    void *ptr;

    /* create the shared memory object */
    shm_fd = shm_open(name, O_CREAT | O_RDRW, 0666);

    /* configure the size of the shared memory object */
    ftruncate(shm_fd, size);

    /* memory map the shared memory object */
    ptr = mmap(0, size, PROT_WRITE, MAP_SHARED, shm_fd, 0);

    /* save array to the shared memory object. */
    /*****WHERE I LOSE IT*****/

    return 0;
}

上下文程序:(不是POSIX)

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

int main (int argc, char *argv[])
{
    char files [20][2][100]; 
    files [0][0][0] = '\0';
    char file_name[100];

    char file_contents[100];
    char search[100];

    char answer;
    int again = 0;
    int counter;
    int i = 0;

    /**************************************************/

    while (again == 0)
    {
        printf("Enter a filename:  ");
        scanf("%s", &file_name);
        getchar();
        printf("Enter file contents (string):  ");
        fgets (file_contents, 100, stdin);

        for (i = 0; i < 20; i++)
        {
            if (files[i][0][0] == '\0')
            {
                strcpy(files[i][0],file_name);
                strcpy(files[i][1],file_contents);
                files [i+1][0][0] = '\0';       
                break;
            }
            else if (i == 19)
            {
                printf("ERROR: The directory is full.\n\n");
            }
        }

        counter++; 

        printf("Save another file y/n ?:  ");
        scanf(" %c", &answer);

        if (answer == 'n')
        {
            again = 1;
        }

    }
    printf("\n\n");
    again = 0;

    /**************************************************/

    printf("You have saved the following files:\n");
    for (i = 0; i < 20; i++)
    {
        if (files[i][0][0] == '\0')
        {
            break;
        }

        printf("%s \n", files[i][0]);
    }
    printf("\n\n");

    /**************************************************/

    printf("Would you like to open a file? (y/n) ?:  ");
    scanf(" %c", &answer);
    if (answer == 'n')
        again = 1;

    while (again == 0)
    {
        printf("Enter a filename:  ");
        scanf(" %s", &file_name);

        for (i = 0; i < 20; i++)
        {
            if (strcmp(files[i][0], file_name) == 0)
            {
                printf("%s \n", files[i][1]);       
                break;
            }
            else if (i == 19)
            {
                printf("ERROR: The file was not found.\n\n");
            }
        }

        printf("Search for another file (y/n) ?:  ");
        scanf(" %c", &answer);

        if (answer == 'n')
        {
            again = 1;
        }
        printf("\n\n");
    }


    getchar();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

代码有一个指向共享内存的指针 因此,就像任何指针一样 代码可以访问共享内存中的任何特定项 通过索引该指针。

#define INDEX_1_SIZE (20)
#define INDEX_2_SIZE (2)
#define INDEX_3_SIZE (100)
#define SIZE         (INDEX_1_SIZE * INDEX_2_SIZE * INDEX_3_SIZE)
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);

然后:

int i, j, k; // loop counters

// initialize the shared memory to '\0'
for(i=0;i<INDEX_1_SIZE; i++_
{
    for(j=0; j<INDEX_2_SIZE; j++)
    {
        for(k=0;k<INDEX_3_SIZE; k++)
        {
            ptr[i][j][k] = '\0';
        }
    }
}

有更快的方法来执行初始化到&#39; \ 0&#39; 例如:

memset( ptr, '\0', SIZE );

不需要本地变量:&#39;文件&#39;

但是,由于许多不同的进程可以访问 同时共享内存,
代码需要一个所有进程都使用的命名信号量 所以只有一个进程正在访问共享内存 任何一次,以避免'比赛'#39;条件。 这里是信号量的一个很好的讨论,以及示例用法     http://www.cs.cf.ac.uk/Dave/C/node26.html 代码应检查错误,如下所示: (当然,使用您自己的变量名称)

des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);

if (des_mutex < 0)
{
    perror("failure on shm_open on des_mutex");
    exit(1);
}

if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1)
{
    perror("Error on ftruncate to sizeof pthread_cond_t\n");
    exit(-1);
}