XanJo
XanJo

Reputation: 41

How can I store and access data in shared memory between two programs?

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;
}

Upvotes: 1

Views: 682

Answers (1)

tsoa
tsoa

Reputation: 131

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]);
}

Upvotes: 4

Related Questions