当我们从不同的上下文调用msync时,文件内容不是持久的

当我们从不同的上下文调用msync时,文件内容不是持久的,c,linux,memory,C,Linux,Memory,我有两个上下文,即process1和process2,它们共享相同的映射区域,process1在大多数情况下将数据同步到文件,然而,process2在系统重新启动之前只同步一次,以确保所有数据都同步。我发现在系统重新启动之前,文件中的数据是完整的,一旦系统重新启动之后出现,我发现process2单独同步的数据丢失了。 注意: mmap标志:两个进程共享的映射 msync标志:两个进程的msu同步 不存在带流程的群集问题 检查所有进程的错误代码 很抱歉,我无法共享完整的代码,但我已经粘贴了它的最小

我有两个上下文,即process1和process2,它们共享相同的映射区域,process1在大多数情况下将数据同步到文件,然而,process2在系统重新启动之前只同步一次,以确保所有数据都同步。我发现在系统重新启动之前,文件中的数据是完整的,一旦系统重新启动之后出现,我发现process2单独同步的数据丢失了。

注意:

  • mmap标志:两个进程共享的映射
  • msync标志:两个进程的msu同步
  • 不存在带流程的群集问题
  • 检查所有进程的错误代码
  • 很抱歉,我无法共享完整的代码,但我已经粘贴了它的最小部分,我认为这应该可以做到。

    **/*Process1(Daemon process)
    * This process does syncing on two files int_fd and ext_fd. It stacks upto 50 messages and * then does a sync for every 50 messages.If the system goes for reboot within these 50     * messages then process2 does syncing before going for reboot. 
    */**
        int_cntr -> file1 data counter(when int_cntr==50 does syncing for file1) 
        ext_cntr -> file2 data counter(when ext_cntr==50 does syncing for file2)
        my_flg -> this flag will be set only when any counter reaches 50.
        int_fd-> file1 to be synced
        ext_fd-> file2 to be synced
    
        **/*This is a daemon process so mapping is done only once during booting of this    process it is done exactly as shown in process2*/**
    
    **/*Counter value check*/**
          **/*checks counter values int_cntr and ext_cntr and sets flag "**my_flg**"only when any of the counter reaches 50,.*/** 
    
    **/*Syncing part*/**
    -> checks the **my_flg** if it is set,then files will be locked.
    -> Uses locks/Unlocks with same flags mentioned in process2.
    -> Call msync with MS_SYNC,exact flags are used as shown in process2
    -> reset the corresponding counter
    -> if the my_flg is not set then data will be added to the queue syncing will not be done.
    
    
    
    **/*Process2
    * This process will be called when system goes for reboot,before going for reboot it syncs * the data to corresponding files.
    */**
        int_fd-> file1 to be synced
        ext_fd-> file2 to be synced
    
                ha_int_file = mmap(0, sizeof (file1), PROT_READ | PROT_WRITE,
                                    MAP_SHARED, int_fd, 0);
                ha_ext_file = mmap(0, sizeof (file2), PROT_READ | PROT_WRITE,
                                    MAP_SHARED, ext_fd, 0);
    
                if(ha_int_file== MAP_FAILED || ha_ext_file==MAP_FAILED)
                    printf("Process2 mmap failed,errno =%d\n",errno);
                /*
                 * Take the LOCK for syncing file1
                 */
                if ((flock_rc = flock(int_fd, LOCK_EX)) != 0) {
                    printf("Forcesync Internal file lock failed##############\n");
                    rc = ERROR;
                } else {
                    if(msync(ha_int_file, sizeof (rls_storage_file_t), MS_SYNC | MS_INVALIDATE)) {
                        printf("Forcesync Internal file sync failed,errno =%d##############\n",errno);
                        rc = ERROR;
                    } else
                        printf("Force sync successful for internal file#####################\n");
                /*
                 * Release the lock on file1
                 */    
                    if ((flock_rc = flock(int_fd, LOCK_UN)) != 0) {
                        printf("Forcesync Internal file un-lock failed##############\n");
                        rc = ERROR;
                    }
    
                }
    
                /*
                 * Take the LOCK for syncing file2
                 */
                if ((flock_rc = flock(ext_fd, LOCK_EX)) != 0) {
                    printf("Forcesync External file lock failed##############\n");
                    rc = ERROR;
                } else {
                    if(msync(ha_ext_file, sizeof (rls_storage_file_t), MS_SYNC | MS_INVALIDATE)) {
                        printf("Forcesync External file sync failed=%d##############\n",errno);
                        rc = ERROR;
                    } else
                        printf("Force sync successful for external file#####################\n");
                /*
                 * Release the LOCK on file2
                 */    
                    if ((flock_rc = flock(ext_fd, LOCK_UN)) != 0) {
                        printf("Forcesync External file un-lock failed##############\n");
                        rc= ERROR;
                    }
                }
    
                close(int_fd);
                close(ext_fd);
    
    问题摘要:

    假设我已收到255条消息,因为每50条消息的同步将由process1完成,因此process1将同步250条消息。现在,process1将剩余的消息(5条消息)添加到队列中。假设系统现在重新启动,Process2将把这5条消息同步到相应的文件。在通过process2同步后,我在系统重新启动前复制了一份文件。我发现在重新启动前复制的文件中的数据完好无损,而在系统启动后,我发现仅通过process2同步的数据丢失。根据我们的示例,仅流程2同步的最后5条消息丢失

    注意: 在重新启动前从同一进程(即进程1)同步时,我看不到问题,只有在重新启动前从进程2同步时,我才看到问题。

    **/*Process1(Daemon process)
    * This process does syncing on two files int_fd and ext_fd. It stacks upto 50 messages and * then does a sync for every 50 messages.If the system goes for reboot within these 50     * messages then process2 does syncing before going for reboot. 
    */**
        int_cntr -> file1 data counter(when int_cntr==50 does syncing for file1) 
        ext_cntr -> file2 data counter(when ext_cntr==50 does syncing for file2)
        my_flg -> this flag will be set only when any counter reaches 50.
        int_fd-> file1 to be synced
        ext_fd-> file2 to be synced
    
        **/*This is a daemon process so mapping is done only once during booting of this    process it is done exactly as shown in process2*/**
    
    **/*Counter value check*/**
          **/*checks counter values int_cntr and ext_cntr and sets flag "**my_flg**"only when any of the counter reaches 50,.*/** 
    
    **/*Syncing part*/**
    -> checks the **my_flg** if it is set,then files will be locked.
    -> Uses locks/Unlocks with same flags mentioned in process2.
    -> Call msync with MS_SYNC,exact flags are used as shown in process2
    -> reset the corresponding counter
    -> if the my_flg is not set then data will be added to the queue syncing will not be done.
    
    
    
    **/*Process2
    * This process will be called when system goes for reboot,before going for reboot it syncs * the data to corresponding files.
    */**
        int_fd-> file1 to be synced
        ext_fd-> file2 to be synced
    
                ha_int_file = mmap(0, sizeof (file1), PROT_READ | PROT_WRITE,
                                    MAP_SHARED, int_fd, 0);
                ha_ext_file = mmap(0, sizeof (file2), PROT_READ | PROT_WRITE,
                                    MAP_SHARED, ext_fd, 0);
    
                if(ha_int_file== MAP_FAILED || ha_ext_file==MAP_FAILED)
                    printf("Process2 mmap failed,errno =%d\n",errno);
                /*
                 * Take the LOCK for syncing file1
                 */
                if ((flock_rc = flock(int_fd, LOCK_EX)) != 0) {
                    printf("Forcesync Internal file lock failed##############\n");
                    rc = ERROR;
                } else {
                    if(msync(ha_int_file, sizeof (rls_storage_file_t), MS_SYNC | MS_INVALIDATE)) {
                        printf("Forcesync Internal file sync failed,errno =%d##############\n",errno);
                        rc = ERROR;
                    } else
                        printf("Force sync successful for internal file#####################\n");
                /*
                 * Release the lock on file1
                 */    
                    if ((flock_rc = flock(int_fd, LOCK_UN)) != 0) {
                        printf("Forcesync Internal file un-lock failed##############\n");
                        rc = ERROR;
                    }
    
                }
    
                /*
                 * Take the LOCK for syncing file2
                 */
                if ((flock_rc = flock(ext_fd, LOCK_EX)) != 0) {
                    printf("Forcesync External file lock failed##############\n");
                    rc = ERROR;
                } else {
                    if(msync(ha_ext_file, sizeof (rls_storage_file_t), MS_SYNC | MS_INVALIDATE)) {
                        printf("Forcesync External file sync failed=%d##############\n",errno);
                        rc = ERROR;
                    } else
                        printf("Force sync successful for external file#####################\n");
                /*
                 * Release the LOCK on file2
                 */    
                    if ((flock_rc = flock(ext_fd, LOCK_UN)) != 0) {
                        printf("Forcesync External file un-lock failed##############\n");
                        rc= ERROR;
                    }
                }
    
                close(int_fd);
                close(ext_fd);
    

    有人能给我简要介绍一下失效标志吗?在这种情况下,它能做些什么。

    不是答案,只是一些想法。通常,如果您正在共享内存,您将首先共享内存,然后将所述内存映射到文件

    只要通过某种合法的共享内存机制(如shmat/shmget)获得共享内存,就可以在进程之间共享内存。即使您将使用共享内存,您也可能希望使用提供内存屏障/检查点的线程原语与该内存交互

    如果不能使用线程原语,可以使用gcc原语(如uu sync_synchronize())在代码中手动创建内存屏障。Visual Studio和其他编译器可能类似


    一旦您确信两个进程之间的内存是一致的,无论谁想要执行最后的同步步骤,都应该调用msync、munmap,然后退出。

    即使您无法共享原始代码,您至少可以尝试创建一个显示相同行为的最小示例。您好,我已经在这里和那里添加了部分代码和解释,以使其具有一定的形状,请帮助我进一步调试该问题。嗨,Claris,内存一致是什么意思,我在系统重新启动之前复制了一份文件,我在那里找到了我的数据,那么它是一致的吗?。但是重新启动后,我没有找到单独同步的最后一部分数据。此外,我是一个初学者。你能解释一下内存障碍是什么吗?我不确定我是否遵循了你的第一句话。文件一经写入就不会被取消写入。re:内存障碍,wikipedia it。我忘了再提一件事,如果在重新启动前从process1同步,我看不到问题。我只有在从process2同步时才能看到它。