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