Home > Software design >  How can I store and access data in shared memory between two programs?
How can I store and access data in shared memory between two programs?

Time:10-20

I have a homework assignment to write two programs, a producer and a consumer. The producer must take a positive integer as input from the user, preform a calculation on it (in this case, the Collatz conjecture), and store the result in shared memory. The consumer program must access this result and print it.

The issue is that I have been able to create, store, and print character arrays (using mmap and memcpy), but I cannot seem to do the same with integers or integer arrays, which is the type of data I would be producing with my calculations. I did also try storing my calculations as a character array, but was unable to convert the ints to chars.

Currently, the producer program just prints the results to the console instead of storing them.

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

int main()
{
    /* The size (in bytes) of shared-memory object */
    const int SIZE = 4096;

    /* The name of shared-memory object */
    const char* Obj = "Shm";

    /* The shared-memory file descriptor */
    int shm_fd;

    /* The pointer to shared-memory object */
    void* ptr;

    /* Create the shared-memory object */
    shm_fd = shm_open(Obj, O_CREAT | O_RDWR, 0666);

    /* Configure the size of the shared-memory object */
    ftruncate(shm_fd, SIZE);

    /* Map the shared-memory object in the address space of the process */
    ptr = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);

    if (ptr == MAP_FAILED)
    {
        printf("Map failed\n");
        return -1;
    }


    //** NEW CODE //

    // calculate based on user input 
    int userInput; // variable to store user int input

    printf("please input a starting number for the collatz conjecture: \n");
    if (scanf("%d", &userInput) == 1) {
        // print each number in the conjecture 
        printf("%d", userInput);
        
        
        // TEST AREA 
    
        int input2 = 5; // THIS WORKS TO SAVE A STRING, BUT NOT INTS
        
        //char inputAr[SIZE];

        //char temp[] = (char)input2;
        //strcat(inputAr, temp);
        
        memcpy(ptr, &input2, SIZE);

        //  TEST AREA

        //char input[SIZE];
        //char temp[10];
        //strcpy(temp, "40123456");
        ////char temp[] = "4";
        //strcat(input, temp);
        //strcpy(temp, " 6");
        //strcat(input, temp);
        //memcpy(ptr, &input, SIZE);




        printf(" ");
        while (userInput != 1) {
            if (userInput % 2 == 0) {
                userInput = userInput / 2;
                printf("%d", userInput);
                printf(" ");
            }
            else {
                userInput = userInput * 3   1;
                printf("%d", userInput);
                printf(" ");
            }
        }// end while

    }

    //** END NEW CODE

    /* Create a message and write it to the shared-memory object */
    //printf("Please input a character string: \n");
    //fgets(ptr, SIZE, stdin);
    printf("Writing the message to the shared memory is done! \n");

    return 0;
}
Consumer
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main()
{

    /* The size (in bytes) of shared-memory object */
    const int SIZE = 4096;

    /* The name of shared-memory object */
    const char* Obj = "Shm";

    /* The shared-memory file descriptor */
    int shm_fd;

    /* The pointer to shared-memory object */
    void* ptr;

    /* Open the shared-memory object */
    shm_fd = shm_open(Obj, O_RDONLY, 0666);

    if (shm_fd == -1)
    {
        printf("Shared memory failed\n");
        exit(-1);
    }

    /* Map the shared-memory object in the address space of the process */
    ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);

    if (ptr == MAP_FAILED)
    {
        printf("Map failed\n");
        exit(-1);
    }

    
    /* Read from the shared-memory object */
    //printf("Test message: %d", (int*)ptr);
    printf("\n");
    printf("The message read from the shared memory: %s", (char*)ptr);
    

    /* Remove the shared-memory object */
    if (shm_unlink(Obj) == -1)
    {
        printf("Error removing %s\n", Obj);
        exit(-1);
    }

    return 0;
}

CodePudding user response:

Single Integer

Remember that in the producer program you have stored the integer input2 inside the shared memory, so you need to print it out as an integer, not as a character array. Instead of

printf("The message read from the shared memory: %s", (char *)ptr);

you need to write it as

int *integer_array = (int *) ptr;
printf("The message read from the shared memory: %d", *integer_array);

This casts ptr (which is a void *) type into an integer pointer (int *), which you can dereference to get the value of input2. Additionally, "%d" is used for integers instead of "%s".

Integer Array

To print out an array of integers, not just a single one, you'd have to have enough space in ptr for number_of_ints * sizeof(int). In each Collatz conjecture iteration, you just store the result in the array like so:

int *integer_array = (int *) ptr;
while (userInput != 1) {
    if (userInput % 2 == 0) {
        userInput = userInput / 2;
    } else {
        userInput = userInput * 3   1;
    }

    *(integer_array  ) = userInput;
}

Once the producer program has finished, the consumer program can print each of these numbers out like this:

int *integer_array = (int *) ptr;
for (int i = 0; i < number_of_ints; i  ) {
    printf("%d ", integer_array[i]);
}
  • Related