作业求助:如何在生产者消费者程序间用共享内存存取整数数据
问题描述
我有一项作业任务,需要编写生产者与消费者两个程序:
- 生产者接收用户输入的正整数,执行Collatz猜想计算,并将结果存入共享内存;
- 消费者程序读取共享内存中的结果并打印。
目前我已经能通过mmap和memcpy实现字符数组的共享内存创建、存储与打印,但无法对整数或整数数组执行相同操作——而Collatz的计算结果正是整数类型。我也曾尝试将计算结果转为字符数组存储,但没能完成整数到字符的转换。当前生产者程序仅能将结果打印到控制台,无法存入共享内存。
以下是我的代码:
生产者代码
#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; }
消费者代码
#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; }
解决方案
有两种可行的方式解决这个问题:直接存储整数数组,或者将计算结果格式化为字符串存储。
方式一:存储整数数组
共享内存可以直接存储整数数组,只需在共享内存开头记录数组的元素个数,方便消费者读取完整序列。
修改后的生产者代码
#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() { const int SIZE = 4096; const char* Obj = "Shm"; int shm_fd; void* ptr; shm_fd = shm_open(Obj, O_CREAT | O_RDWR, 0666); ftruncate(shm_fd, SIZE); ptr = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { printf("Map failed\n"); return -1; } int userInput; printf("please input a starting number for the collatz conjecture: \n"); if (scanf("%d", &userInput) == 1) { int* collatz_seq = (int*)ptr; int count = 0; // 存储序列并计数 collatz_seq[count++] = userInput; printf("%d", userInput); int temp = userInput; while (temp != 1) { if (temp % 2 == 0) { temp /= 2; } else { temp = temp * 3 + 1; } collatz_seq[count++] = temp; printf(" %d", temp); } // 将元素个数存到数组开头,序列从第二个位置开始 memmove(collatz_seq + 1, collatz_seq, count * sizeof(int)); collatz_seq[0] = count; printf("\nWriting the sequence to shared memory done!\n"); } return 0; }
修改后的消费者代码
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/mman.h> int main() { const int SIZE = 4096; const char* Obj = "Shm"; int shm_fd; void* ptr; shm_fd = shm_open(Obj, O_RDONLY, 0666); if (shm_fd == -1) { printf("Shared memory failed\n"); exit(-1); } ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { printf("Map failed\n"); exit(-1); } int* collatz_seq = (int*)ptr; int count = collatz_seq[0]; printf("\nCollatz sequence from shared memory:\n"); for (int i = 1; i <= count; i++) { printf("%d", collatz_seq[i]); if (i != count) { printf(" "); } } printf("\n"); if (shm_unlink(Obj) == -1) { printf("Error removing %s\n", Obj); exit(-1); } return 0; }
方式二:格式化为字符串存储
使用snprintf将整数序列格式化为字符串,直接存入共享内存,消费者可以按字符串读取打印。
修改后的生产者代码
#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() { const int SIZE = 4096; const char* Obj = "Shm"; int shm_fd; void* ptr; shm_fd = shm_open(Obj, O_CREAT | O_RDWR, 0666); ftruncate(shm_fd, SIZE); ptr = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { printf("Map failed\n"); return -1; } int userInput; printf("please input a starting number for the collatz conjecture: \n"); if (scanf("%d", &userInput) == 1) { char* seq_str = (char*)ptr; int pos = 0; // 写入第一个数 pos += snprintf(seq_str + pos, SIZE - pos, "%d", userInput); printf("%d", userInput); int temp = userInput; while (temp != 1) { if (temp % 2 == 0) { temp /= 2; } else { temp = temp * 3 + 1; } // 写入空格和下一个数 pos += snprintf(seq_str + pos, SIZE - pos, " %d", temp); printf(" %d", temp); } printf("\nWriting the sequence to shared memory done!\n"); } return 0; }
修改后的消费者代码
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/mman.h> int main() { const int SIZE = 4096; const char* Obj = "Shm"; int shm_fd; void* ptr; shm_fd = shm_open(Obj, O_RDONLY, 0666); if (shm_fd == -1) { printf("Shared memory failed\n"); exit(-1); } ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { printf("Map failed\n"); exit(-1); } printf("\nCollatz sequence from shared memory:\n%s\n", (char*)ptr); if (shm_unlink(Obj) == -1) { printf("Error removing %s\n", Obj); exit(-1); } return 0; }
内容的提问来源于stack exchange,提问作者XanJo
相关产品推荐
相关产品推荐

