在FAT32上自己创建文件后无法删除文件

时间:2018-08-15 14:46:41

标签: c linux filesystems posix embedded-linux

我有一个程序(用C11,POSIX.1-2008编写并在嵌入式Linux上运行),该程序会定期创建文件,并在一段时间后再次将其删除。

在EXT4文件系统上创建和删除文件(都是由我的程序完成)时,一切都像一个超级按钮。

现在有趣的事情发生在使用FAT32文件系统时:虽然程序能够写入文件,但是当尝试再次删除它们时,它会冻结。冻结的类型是相应的进程暂停,但不退出,并且在使用诸如top的程序查看VIRT,RES,SHR,%CPU,%MEM之类的利用率为零时。同级进程发生相同的事情,该进程与试图通过FIFO删除文件的进程通信。父进程保持活动状态。另外,文件删除发生在进程的单独线程中,因此不应停止整个进程。父进程是作为守护进程启动的,这可能就是两个孩子保持在顶部可见的原因。

                                           |--------------|
                                           |Parent process|
                                           |--------------|
                                                  |
                       ---------------------------|---------------
                      ||                                         ||
                      \/                                         ||
|--------------------------------------------|                   ||
|     Process containing file deletion       |                   \/
||--------------------| |-------------------||             |-------------|
||File deletion thread| |Main process thread|| <- FIFOs -> |Other process|
||--------------------| |-------------------||             |-------------|
|--------------------------------------------|

如果FAT32上的目录是预先创建的(在控制台中,在其他PC上或在其他PC上),或者由程序本身使用

创建,则行为不会改变
mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)

我确实检查所有函数的返回值,但是没有检测到任何异常。删除调用对绝对文件名起作用。

我可以在控制台中删除文件而没有任何问题(但是程序仍然停止)。

程序以root身份运行。

有人知道为什么我有这种行为吗?

这是在文件删除线程中运行的代码:

void* _histDeleteFilesThread(void* context)
{
HistCollection* collection = ((HistThreadContext*)context)->collection;
int* retVal = ((HistThreadContext*)context)->retVal;
free(context);
*retVal = -1;
bool finished = false;

if(collection == NULL){
    logging(stderr, "Bad input to runner thread\n");
    pthread_exit(retVal);
}
else{
    if(pthread_mutex_lock(collection->startNewSearch) != 0){
        logging(stderr, "Failed to lock mutex to start a new search\n");
        pthread_exit(retVal);
    }
    else if(sem_wait(collection->canDeleteFiles) != 0){
        pthread_mutex_unlock(collection->startNewSearch);
        logging(stderr, "Failed to acquire semaphore to delete files\n");
        pthread_exit(retVal);
    }

    while(!finished){
        if(pthread_mutex_lock(collection->fileDeletionDataAccess) != 0){
            sem_post(collection->canDeleteFiles);
            pthread_mutex_unlock(collection->startNewSearch);
            logging(stderr, "Failed to acquire file deletion data access mutex\n");
            pthread_exit(retVal);
        }

        char* file_to_delete;

        if((file_to_delete = _histFIFOPop(&collection->fileToRemove)) == NULL){
            finished = true;
            *collection->fileDeletionThreadRunning = false;
        }
        else{
            char* full_file_name = _histFileCreateAbsolutePath(collection, file_to_delete);
            if(remove(full_file_name) != 0){
                logging(stderr, "Failed to delete file %s\n", full_file_name);
                finished = true;
                *collection->fileDeletionThreadRunning = false;
            }
            else{
                logging(stdout, "Removed %s\n", full_file_name);
            }
            free(full_file_name);
            free(file_to_delete);
        }

        if(pthread_mutex_unlock(collection->fileDeletionDataAccess) != 0){
            sem_post(collection->canDeleteFiles);
            pthread_mutex_unlock(collection->startNewSearch);
            logging(stderr, "Failed to lock mutex to start a new search\n");
            pthread_exit(retVal);
        }
    }

    if(sem_post(collection->canDeleteFiles) != 0){
        pthread_mutex_unlock(collection->startNewSearch);
        logging(stderr, "Failed to lock mutex to start a new search\n");
        pthread_exit(retVal);
    }
    else if(pthread_mutex_unlock(collection->startNewSearch) != 0){
        logging(stderr, "Failed to lock mutex to start a new search\n");
        pthread_exit(retVal);
    }

    *retVal = 0;
    pthread_exit(retVal);
}

}

简要介绍一下系统如何工作:另一个进程生成数据,该数据通过POSIX FIFO传递到包含文件删除的进程。在该过程中,首先将数据缓冲在RAM中,然后写入文件,然后将该文件的文件名存储在第一个SW FIFO中。在文件位于第一个SW FIFO中的时间内,可以搜索和使用该SW FIFO中所有文件中的数据以及缓冲区中的所有数据(所有搜索都在单独的线程中,因为它们的计算量很大,因此我们必须保持实时响应能力)。当文件变旧时,将其移至第二个SW FIFO,并启动文件删除线程。该线程必须等到所有其他搜索都终止之后再删除文件,否则它可能仍被另一个线程使用,并且直到文件删除线程删除了第二个SW FIFO中的文件后,才能开始新的搜索(文件删除线程具有更高的运行优先级(通过互斥量和信号量实现),以避免FIFO溢出。

0 个答案:

没有答案