我想从多个文件中读取并使用 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;
}
}
有没有我错过的更好的方法?
有没有我错过的更好的方法?
可以使用多个线程(轻量级进程)而不是使用多个进程。 线程共享父进程的内存空间,通过
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(¶m->content, ¶m->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(¶ms[i].handle, NULL, run, ¶ms[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
参考文献: