首页 > 解决方案 > 如何同步文件读取以读取相同的文件

问题描述

问题

大家好,我正在尝试让两个进程读取同一个文件。这很容易,但是我需要两个进程以这样的方式读取文件,即它们不会读取相同的数据,也就是当一个进程读取并更改指针的位置时,然后它会更改另一个进程上的指针,直到EOF。我如何实现这一目标?

我当前的实现将读取每个进程的文件,然后从两个进程的 az 读取。

我想要输入

定义

然后给出的输出

程序 1 读取:a程序
2 读取:b程序 1
读取:c程序 2
读取:d程序 1
读取:e程序
2 读取:f
找到 EOF,退出程序

背景

我正在为此操作系统课程构建的项目的背景。该项目将执行一个名为 program1 的程序,然后该程序将创建 9 个管道,一个信号量,一个共享内存,用于计算已读取的字符数,然后还接受文件名的命令行参数。第一个程序还将在创建其他所有内容后生成 9 个子节点并将所有先前的信息传递给它们,一个从 program1 到特定子节点的管道、信号量、共享内存位置、文件名。

每个孩子都可以同步访问一个文件,共享内存。然后每个孩子将随机读取 1-10 个字符,然后将共享内存增加该数量。然后,孩子们将发送当前具有访问权限的程序的名称以及已读取的字符并将它们写入管道。如果他们到达行尾,他们还将在写入管道的同一字符串中写入读取的字符总数。当特定的孩子这样做时,它会将执行传递给 program1 执行。

当程序一通过信号量获得执行权限时,它将读取通过所有非阻塞管道发送的字符串。然后将该字符串写入输出文件,然后释放信号量供任何子级再次使用,直到达到 eof。

程序尝试

这是一个示例程序,用于显示发生了什么问题。我正在尝试将文件名传递给孩子然后父母和孩子都试图同时同步读取文件。

家长

#define  key (3000)

int main() 
{ 


    FILE *fPTR;
    int c, semID;

    struct sembuf operations[1];


    pid_t PID1;

    int argCount = 2;
    int size = 20;

    union semun {


        int value;
        struct semid_ds *buffer;
        ushort *array;

    } arg;


    char **args = (char **) malloc( (argCount) * (sizeof (char *) ));
    args[0] =     (char *)  malloc( (size)     * (sizeof (char  ) ));
    args[1] =     (char *)"inputTest.txt";



    semID = semget(key, 3, 0666 | IPC_CREAT);


    fPTR = fopen("inputTest.txt", "r");


    if(semctl(semID, 0, SETVAL, arg) < 0){


        fprintf(stderr, "was unable to set value of sempahore 0" );
        exit(0);
    }



    PID1 = fork();



    if(PID1 == 0){

        sprintf(args[0], "%d", semID);


        if(execvp("./TestReadingChild", args) == -1){

            printf("failed to execute TestReadingChild\n");
            exit(0);
        }

    }

    if(PID1 >= 0){


        while(1){


            if(semctl(semID, 0, GETVAL, arg) == 0){

                if((c = fgetc(fPTR)) != EOF){

                    printf("Program1 read: %c\n", (char) c);
                }else{

                    fclose(fPTR);
                    break;
                }





                operations[0].sem_num = 0;
                operations[0].sem_op = 1;
                operations[0].sem_flg = 0;

                semop(semID, operations, 1);


            }


        }
    }


}

孩子

#define  key (3000)

int main(int argc, char *argv[]) 
{ 

    char *fileName = argv[1];
    FILE *fPTR;
    int semID = atoi(argv[0]);
    int c;

    struct sembuf operations[1];

    pid_t PID1;

    int argCount = 2;
    int size = 20;

    union semun {


        int value;
        struct semid_ds *buffer;
        ushort *array;

    } arg;

    char **args = (char **) malloc( (argCount) * (sizeof (char *) ));
    args[0] =     (char *)  malloc( (size)     * (sizeof (char  ) ));
    args[1] =     (char *)  fileName;


    semID = semget(key, 3, 0666 | IPC_CREAT);
    fPTR = fopen(fileName, "r");


    while(1){


        if(semctl(semID, 0, GETVAL, arg) == 1){

            if((c = fgetc(fPTR)) != EOF){

                printf("Program2 read: %c\n", (char) c);
            }else{
                fclose(fPTR);
                break;
            }





            operations[0].sem_num = 0;
            operations[0].sem_op = -1;
            operations[0].sem_flg = 0;

            semop(semID, operations, 1);
        }


    }
}

标签: ciosynchronization

解决方案


在两个进程之间创建共享内存并将文件指针放入其中。

为此,只需将文件指针放在共享内存上,即您需要使用 sizeof(FILE *) 在 shm 中分配内存,这只是一个整数值;但是当两个进程想要访问它时要小心 shm 并发。你可以用信号量做到这一点。


推荐阅读