【问题标题】:Fibonacci shared memory processes between two c files两个c文件之间的斐波那契共享内存进程
【发布时间】:2018-10-10 20:29:25
【问题描述】:

您好,我在 c 中有一个文件,它从父级到子级共享内存,但我需要将我的代码分成两个单独的文件,同时仍共享内存。我需要父级创建共享内存并获取 fib 编号的输入。然后子进程打开共享内存对象读取值n,并用fib(n)的值覆盖n值。并显示 fib 系列。这就是我现在拥有的

#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>

// So we could use other sizes without editing the source.
#ifndef MAX_SEQUENCE
# define MAX_SEQUENCE 10
#endif

// Check that MAX_SEQUENCE is large enough!
#if MAX_SEQUENCE < 2
#error MAX_SEQUENCE must be at least 2
#endif

typedef struct{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
} shared_data;

int main()
{
    int a, b, m, n, i;
    a = 0; b = 1;

    printf("Enter the number of a Fibonacci Sequence:\n");
    // Always check whether input conversion worked
    if (scanf("%d", &m) != 1) {
        printf("Invalid input, couldn't be converted.\n");
        return EXIT_FAILURE;
    }

    if (m <= 0) {
        printf("Please enter a positive integer\n");
        return EXIT_FAILURE; // exit if input is invalid
    } else if (m > MAX_SEQUENCE) {
        printf("Please enter an integer less than %d\n", MAX_SEQUENCE);
        return EXIT_FAILURE; // exit if input is invalid
    }

    /* the identifier for the shared memory segment */
    int segment_id;

    /* the size (in bytes) of the shared memory segment */
    size_t segment_size = sizeof(shared_data);

    /* allocate a shared memory segment */
    segment_id = shmget(IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR);

    // Check result of shmget
    if (segment_id == -1) {
        perror("shmget failed");
        return EXIT_FAILURE;
    }

    /* attach the shared memory segment */
    shared_data *shared_memory = shmat(segment_id, NULL, 0);

    // Check whether attaching succeeded
    if ((void*)shared_memory == (void*)-1) {
        perror("shmat failed");
        goto destroy; // clean up
    }
    printf("\nshared memory segment %d attached at address %p\n", segment_id, (void*)shared_memory);

    shared_memory->sequence_size = m;
    pid_t pid;
    pid = fork();
    if (pid == 0){
        printf("Child is producing the Fibonacci Sequence...\n");
        shared_memory->fib_sequence[0] = a;
        shared_memory->fib_sequence[1] = b;
        for (i = 2; i < shared_memory->sequence_size; i++){
            n = a+b;
            shared_memory->fib_sequence[i] = n;
            a = b;
            b = n;
        }
        printf("\nChild ends\n");
    }
    else{
        printf("Parent is waiting for child to complete...\n");
        wait(NULL);
        printf("Parent ends\n");
        for(i = 0; i < shared_memory->sequence_size; i++) {
            printf("%ld ", shared_memory->fib_sequence[i]);
        }
        printf("\n");
    }

    /* now detach the shared memory segment */
    if (shmdt(shared_memory) == -1) {
        fprintf(stderr, "Unable to detach\n");
    }

destroy:
    /* now remove the shared memory segment */
    shmctl(segment_id, IPC_RMID, NULL);

    return 0;
}

【问题讨论】:

  • 你那里的意大利面看起来很漂亮。
  • 题中没有题。
  • 那么您是问如何在未知操作系统中创建和使用共享内存?
  • 我想知道如何在linux系统中两个c文件之间共享内存来完成上述程序。
  • @AlexGordo 当您说两个 C 文件时,您是指两个单独的可执行文件(每个 C 文件都有自己的 main)还是指两个文件链接在一起成为一个可执行文件?跨度>

标签: c shared-memory fibonacci


【解决方案1】:

共享记忆有多种选择:

数据池 - 数据池是内核根据请求提供给进程的分配位置。然后其他进程使用用于创建数据池的名称来连接它并从中读取/写入。

Pipelines - Pipeline 是另一种共享资源的形式,内核再次根据请求提供。不同之处在于管道通常是单向的,而数据池可以被所有进程读取和写入。此外,从管道中读取是破坏性的。

文件 - 您也可以使用最基本的文件,您可能对它很熟悉。

这些是基本的解释,您必须研究这些主题才能完全理解和使用它们。此外,每个操作系统都有使用这些概念的特定方式,但它们都提供了它(以自己的方式)。

【讨论】:

  • 他为什么不能像他已经在做的那样使用shm 函数?
  • @barmar 请帮帮我,我需要把那个文件一分为二,但我需要帮助
  • @AlexGordo 哪一部分你不明白?在两个文件中使用shmget(),使用相同的key,就可以共享内存了。
【解决方案2】:

不要在父进程中附加共享内存,然后在客户端继承它,而是使用ftok() 获取两个进程都使用的公共共享内存密钥。

在当前目录中创建一个文件fibonacci,这将用于调用ftok()

父进程fork子进程时,调用execl()执行子程序,而不是直接包含子代码。子程序不需要任何fork()代码,只需附加到同一个共享内存段并填写结果即可。

fibonacci.h

#ifndef FIBONACCI_H
#define FIBONACCI_H

// So we could use other sizes without editing the source.
#ifndef MAX_SEQUENCE
# define MAX_SEQUENCE 10
#endif

// Check that MAX_SEQUENCE is large enough!
#if MAX_SEQUENCE < 2
#error MAX_SEQUENCE must be at least 2
#endif

#define TOKEN_PATH "fibonacci"

typedef struct{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
} shared_data;

#endif

testparent.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>

#include "fibonacci.h"

int main()
{
    int m, i;
    printf("Enter the number of a Fibonacci Sequence:\n");
    // Always check whether input conversion worked
    if (scanf("%d", &m) != 1) {
        printf("Invalid input, couldn't be converted.\n");
        return EXIT_FAILURE;
    }

    if (m <= 0) {
        printf("Please enter a positive integer\n");
        return EXIT_FAILURE; // exit if input is invalid
    } else if (m > MAX_SEQUENCE) {
        printf("Please enter an integer less than %d\n", MAX_SEQUENCE);
        return EXIT_FAILURE; // exit if input is invalid
    }

    /* the identifier for the shared memory segment */
    int segment_id;

    /* the size (in bytes) of the shared memory segment */
    size_t segment_size = sizeof(shared_data);

    /* Get shared memory token */
    key_t token = ftok(TOKEN_PATH, 0);
    if (token == -1) {
        perror("ftok");
        return EXIT_FAILURE;
    }

    /* allocate a shared memory segment */
    segment_id = shmget(token, segment_size, S_IRUSR | S_IWUSR | IPC_CREAT);

    // Check result of shmget
    if (segment_id == -1) {
        perror("shmget failed");
        return EXIT_FAILURE;
    }

    /* attach the shared memory segment */
    shared_data *shared_memory = shmat(segment_id, NULL, 0);

    // Check whether attaching succeeded
    if ((void*)shared_memory == (void*)-1) {
        perror("shmat failed");
        goto destroy; // clean up
    }
    printf("\nshared memory segment %d attached at address %p\n", segment_id, (void*)shared_memory);

    shared_memory->sequence_size = m;
    pid_t pid;
    pid = fork();
    if (pid == 0){
        execl("./testchild", "./testchild", (char *)NULL);
        perror("execl"); // If it returns it must have failed
        return EXIT_FAILURE;
    }
    else{
        printf("Parent is waiting for child to complete...\n");
        wait(NULL);
        printf("Parent ends\n");
        for(i = 0; i < shared_memory->sequence_size; i++) {
            printf("%ld ", shared_memory->fib_sequence[i]);
        }
        printf("\n");
    }

    /* now detach the shared memory segment */
    if (shmdt(shared_memory) == -1) {
        fprintf(stderr, "Unable to detach\n");
    }

destroy:
    /* now remove the shared memory segment */
    shmctl(segment_id, IPC_RMID, NULL);

    return 0;
}

testchild.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>

#include "fibonacci.h"

int main()
{
    int a, b, n, i;
    a = 0; b = 1;

    /* the identifier for the shared memory segment */
    int segment_id;

    /* the size (in bytes) of the shared memory segment */
    size_t segment_size = sizeof(shared_data);

    /* Get shared memory token */
    key_t token = ftok(TOKEN_PATH, 0);
    if (token == -1) {
        perror("ftok");
        return EXIT_FAILURE;
    }

    /* allocate a shared memory segment */
    segment_id = shmget(token, segment_size, S_IRUSR | S_IWUSR);

    // Check result of shmget
    if (segment_id == -1) {
        perror("shmget failed");
        return EXIT_FAILURE;
    }

    /* attach the shared memory segment */
    shared_data *shared_memory = shmat(segment_id, NULL, 0);

    // Check whether attaching succeeded
    if ((void*)shared_memory == (void*)-1) {
        perror("shmat failed");
        return EXIT_FAILURE;
    }
    printf("\nshared memory segment %d attached at address %p\n", segment_id, (void*)shared_memory);

    printf("Child is producing the Fibonacci Sequence...\n");
    shared_memory->fib_sequence[0] = a;
    shared_memory->fib_sequence[1] = b;
    for (i = 2; i < shared_memory->sequence_size; i++){
        n = a+b;
        shared_memory->fib_sequence[i] = n;
        a = b;
        b = n;
    }
    printf("\nChild ends\n");

    /* now detach the shared memory segment */
    if (shmdt(shared_memory) == -1) {
        fprintf(stderr, "Unable to detach\n");
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 2015-07-05
    • 2011-02-16
    • 1970-01-01
    相关资源
    最近更新 更多