在C中,我想在两个独立的进程中访问一个数组

时间:2018-03-28 02:38:15

标签: c multithreading fork public

这基本上就是我想做的,但输出是垃圾数据。我有什么不同的选项可以让父进程内的子进程可见?

#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int foo[3];                                     //initialize array

    pid_t pid;
    pid = fork();                                   //create child thread

    if (pid == 0) {                                 //child:
        foo[0] = 0; foo[1] = 1; foo[2] = 2;         //populate array
    }

    else {                                          //parent:
        wait(NULL);                                 //wait for child to finish
        printf("%d %d %d", foo[0], foo[1], foo[2]); //print contents of array
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

使用mmap,您可以在父进程中创建共享内存块。这是删除错误检查的基本示例。

您希望确保根据您的需要设置适当的保护和标志。然后将mmap返回的地址移交给您的子流程。

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>

#define LIMIT_MAP 5

void child_worker(void *map)
{
    int map_value = -1;
    int idx = 0;

    while (map_value != LIMIT_MAP) {
        map_value = *((int *) map + (idx * sizeof(int)));
        printf("Map value: %d\n", map_value);
        idx++;
        sleep(2);
    }
}

int main(int argc, char *argv[])
{
    printf("Starting Parent Process...\n");

    long page_size = sysconf(_SC_PAGESIZE);

    void *memory_map = mmap(0, page_size, PROT_WRITE | PROT_READ, 
                                          MAP_SHARED | MAP_ANONYMOUS, 0, 0);

    printf("Memory map created: <%p>\n", memory_map);

    pid_t pid = fork();

    if (pid == 0) {
        sleep(1);
        printf("Starting child process\n");
        child_worker(memory_map);
        printf("Exiting child process...\n");
        return 0;

    } else {

        printf("Continuing in parent process\n");

        int set_values[5] = { 1, 2, 3, 4, 5 };

        for (int i=0; i < 5; i++) {
            printf("Setting value: %d\n", set_values[i]);
            *((int *) memory_map + (sizeof(int) * i)) = set_values[i];
            sleep(1);
        }

        waitpid(pid, NULL, 0);

        printf("Child process is finished!\n");
    }

    return 0;
}

如果fork不是必需项且您的平台允许,pthread是一种选择。根据数组的操作方式,创建一个线程池,为每个工作线程传递一个数组副本。

这是一个人为的例子,但也许你可以从中提取一些东西:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>

#define THREAD_COUNT 3
#define ITER_LIMIT   7

struct worker_params {
    int idx;
    int max;
    bool done;
    double *data;
    double condition;
};

void *worker(void *arg)
{
    struct worker_params *wp = (struct worker_params *) arg;

    int count = 0;

    while ( 1 ) {

        wp->data[wp->idx] = drand48();
        if (wp->max == count)
            wp->done = true;
        sleep(1);

        count++;
    } 

    return NULL;   
}

int main(int argc, char *argv[])
{
    double data[THREAD_COUNT] = { 0.0 };

    pthread_t worker_1, worker_2, worker_3;
    pthread_t worker_threads[] = { worker_1, worker_2, worker_3 };

    struct worker_params wps[] = {
        { .idx=0, .condition=0.1, .data=data, .done=0 },
        { .idx=1, .condition=0.2, .data=data, .done=0 },
        { .idx=2, .condition=0.3, .data=data, .done=0},
    };

    for (int i=0; i < THREAD_COUNT; i++) {
        wps[i].max = (rand() % ITER_LIMIT) + 2;
        pthread_create(&worker_threads[i], NULL, worker, (void *) &wps[i]);
    }

    // Continue on main execution thread

    int running = 1;

    while ( running ) {
        for (int i=0; i < THREAD_COUNT; i++) {
            if (wps[i].done) {
                printf("Limit hit in worker <%d>\n", i + 1);
                running = 0;
                break;
            }

            printf("Data in worker <%d> :: %g\n", i + 1, wps[i].data[i]);
        }

        sleep(1);
    }

    return 0;
}