Фибоначчи разделяет процессы памяти между двумя файлами c - PullRequest
0 голосов
/ 10 октября 2018

Здравствуйте. У меня есть один файл в c, который разделяет память от родителя к потомку, но мне нужно, чтобы мой код был разделен на два отдельных файла, при этом все еще разделяя память.Мне нужен родитель, чтобы создать общую память и получить ввод числа FIB.Затем дочерний процесс открывает объект общей памяти, чтобы прочитать значение n и перезаписать значение n значением fib (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;
}

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Вместо того, чтобы присоединять разделяемую память в родительской и затем наследовать ее в клиенте, используйте ftok(), чтобы получить общий ключ разделяемой памяти, который используется обоими процессами.

Создайте файл fibonacci вВаш текущий каталог, он будет использоваться в вызовах ftok().

Когда родительский элемент разветвляет дочерний процесс, он вызывает 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;
}
0 голосов
/ 11 октября 2018

Существует несколько опций для совместно используемой памяти:

Пулы данных - пул данных - это выделенное местоположение, которое ядро ​​предоставляет процессу по запросу.Затем другие процессы используют имя, которое использовалось для создания пула данных для подключения к нему и чтения / записи из него.

Конвейеры - Конвейер - это еще одна форма совместного использования ресурсов, которую ядро ​​снова предоставляет по запросу.Разница в том, что конвейер обычно односторонний, тогда как пул данных может быть прочитан и записан всеми процессами.Кроме того, чтение из конвейера является разрушительным.

Файлы - вы также можете использовать файлы, которые являются самыми основными, и вы, вероятно, знакомы с ними.

Это основные объяснения, вы должны исследоватьна эти темы, чтобы полностью понять и использовать их.Кроме того, каждая операционная система имеет определенный способ использования этих концепций, но все они предоставляют его (по-своему).

...