分叉读取多个文件并将它们写入单个输出文件

问题描述 投票:0回答:1

我想从多个文件中读取并使用 fork() 将它们写入单个文件。我有 3 个子进程,每个子进程分别读取 3 个输入文件,我想将这些文件的内容写入父进程中的单个输出文件。 例如,我有 3 个

txt
文件,它们在子进程中读取:

sample1.txt => 1 2 3
sample2.txt => 4 5 6
sample3.txt => 7 8 9 

我想在父进程中将它们写入单个output.txt,如下所示:

1 2 3 4 5 6 7 8 9

我无法获得所需的输出文件:

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

int status = 0;
FILE *fptr[3];
char fn[100];
char output[100];
int n = 0;
int i = 0;

int
main()
{
    for (int k = 0; k < 3; k++) {
        if (fork() == 0) {
            sprintf(fn, "sample%d.txt", (k + 1));

            fptr[k] = fopen(fn, "r");

            while (fscanf(fptr[k], "%d", &output[i]) == 1) {
                n++;
                i++;
            }

            for (i = 0; i < n; i++) {
                fscanf(fptr[k], "%d", &output[i]);
            }
        }
        else {
            wait(&status);
            FILE *fp;

            fp = fopen("output.txt", "w+");
            for (int i = 0; i < n; i++) {
                fprintf(fp, "%d ", output[i]);
            }
        }

        printf("Bye\n");
        return 0;
    }
}

有没有我错过的更好的方法?

c fork
1个回答
0
投票

有没有我错过的更好的方法?

可以使用多个线程(轻量级进程)而不是使用多个进程。 线程共享父进程的内存空间,通过

fork
创建的子进程本身就是进程,并且在单独的内存空间中运行。对于进程间通信(IPC),必须使用共享内存对象、管道或其他形式的数据交换。

使用多线程和屏障对象的示例:

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

//number of total threads (input files)
#define NUM_THREADS 4

//thread data passed to each thread
struct thread_param {
    pthread_t handle;
    int       id;
    char*     content;
    size_t    content_size;
};

//global vars
static struct thread_param params[NUM_THREADS];
static pthread_barrier_t barrier;

//thread starting function
//arg is a pointer to struct thread_param
void* run(void *arg)
{
    //cast to proper data type
    struct thread_param *param = (struct thread_param*) arg;

    //generate filename
    char filename[100];
    snprintf(filename, 100, "sample%d.txt", (param->id + 1));

    //read file into buffer
    FILE *in = fopen(filename, "r");
    param->content_size = getdelim(&param->content, &param->content_size, EOF, in);
    fclose(in);

    //the last arriving thread does the multiplexing and cleanup
    if (pthread_barrier_wait(&barrier) == PTHREAD_BARRIER_SERIAL_THREAD) 
    {
        FILE *out = fopen("output.txt", "w+");
        for (int i=0; i < NUM_THREADS; ++i)
        {
            //write in proper order
            fwrite(params[i].content, params[i].content_size, 1, out);
            //free content
            free(params[i].content);
        }
        fclose(out);
    }

    return NULL;
}

int main()
{
    //initialize barrier with the number of threads
    pthread_barrier_init(&barrier, NULL, NUM_THREADS);

    //for each thread
    for (int i=0; i < NUM_THREADS; ++i)
    {
        //prepare thread data
        params[i].id = i;
        params[i].content = NULL;
        params[i].content_size = 0;

        //create thread and invoke starting function with the proper data
        pthread_create(&params[i].handle, NULL, run, &params[i]);
    }

    //for each thread
    for (int i=0; i < NUM_THREADS; ++i) 
    {
        //join the thread, therefore cleanup of thread resources
        pthread_join(params[i].handle, NULL);
    }

    pthread_barrier_destroy(&barrier);
}

用 gcc 编译:

gcc -Wall -pthread -o main main.c

参考文献:

© www.soinside.com 2019 - 2024. All rights reserved.