You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

作业求助:如何在生产者消费者程序间用共享内存存取整数数据

问题描述

我有一项作业任务,需要编写生产者与消费者两个程序:

  • 生产者接收用户输入的正整数,执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:45:43