Implement Lock files on Windows

本文介绍了一个使用Lockfiles实现简单Reader-Writer锁的示例程序。该程序支持读写两种模式,并通过Windows API创建临时文件,确保资源的一致性和互斥访问。

Lock files可以用于进程间进行通信。比如,我们想要让某些资源被多个进程共享,有一个程序用于发布更新的资源,而其他一些程序可以使用最新的资源做一些事情。由于reader程序可能是一些batch file,所以不太可能使用一些比较高级的同步工具来锁定我们需要发布的资源。这样使用lock files将会是比较直接、简单的方法。

我们需要用lock files来实现简单的Reader-Writer锁,也就是当有人需要进行写操作时,所有其他操作都是不允许的。但是当有人进行读操作时,只有读操作时允许的,写操作依然是被禁止的。

#include <windows.h> 
#include <cstdlib> 
#include <cstring> 
#include <iostream> 
#include <tchar.h> 

enum lock_mode {
    lm_shareread,
    lm_exclusive,
    lm_count
};

int main(int argc, char** argv) {
    if (argc >= 2) {
        lock_mode m;
        DWORD dwAccess;
        DWORD dwShareMode;
        if (strcmp(argv[1], "-r") == 0) {
            dwAccess = GENERIC_READ;
            dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE; // share read
            m = lm_shareread;
        } else if (strcmp(argv[1], "-w") == 0) {
            dwAccess = GENERIC_WRITE;
            dwShareMode = FILE_SHARE_DELETE; // do not share read or write, exclusive
            m = lm_exclusive;
        } else {
            std::cerr << "invalid argument/n";
            return EXIT_FAILURE;
        }

        HANDLE hFile;
        hFile = CreateFile(_T("lock"), dwAccess, dwShareMode, NULL,
                           OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
        if (hFile != INVALID_HANDLE_VALUE) {
#ifdef _DEBUG
            char c;
            std::cin >> c;
#endif
            if (m == lm_shareread) {
                std::cout << "read complete/n";
            } else {
                std::cout << "write complete/n";
            }
            CloseHandle(hFile);
            return EXIT_SUCCESS;
        } else {
            if (m == lm_shareread) {
                std::cerr << "Cannot read/n";
            } else {
                std::cerr << "Cannot write/n";
            }
            std::cerr << "Error code: " << GetLastError() << std::endl;
            return EXIT_FAILURE;
        }
    } else {
        std::cerr << "no arguments specified/n";
        return EXIT_FAILURE;
    }
}

这个程序接受2种参数,-r, -w,-r进行读,-w进行写,可以试着模拟两种file locks的情况。

这里我们使用FILE_FLAG_DELETE_ON_CLOSE,由于file locks通常是临时文件,所以当最后一个文件句柄关闭的时候,将会自动删除这个文件,而FILE_ATTRIBUTE_TEMPORARY是说,这是个临时文件,对它的写入将不用写回到磁盘上(不加也没有关系,因为我们这里不会有任何存取操作)。

 

在创建文件时,我们使用了OPEN_ALWAYS。因为如果不存在,我们肯定需要创建一个文件,但是如果已经存在,那么我们希望直接打开这个文件。 如果将它们分开为2个操作: 1. 测试文件是否存在 2. 打开或者创建文件

将会有race condition出现。假设我们测试完后发现文件不存在,那么我们决定创建文件,但是此时另外一个程序也发现文件不存在,也准备创建文件,那么其中一个创建操作必然会失败,这里我们想要的是atomic operation,而OPEN_ALWAYS正好保证了这种情况。

那么根据当前的信息判断,为了满足**Problem Description**: In this task, you will implement a multi-process dataset generator. We have provided you with the `process_labels` function, which generates samples based on labels and font files. Follow the requirements and hints below to complete the code. **Task Requirements**: 1. **Font File Reading**(1 Pt): - Define the variable `font_directory` as the font file storage path `./Font`. Read all `.ttf` and `.ttc` files from this directory and store their paths in the `font_files` list. 2. **Calculate Total Sample Count**(1 Pt): - Set the variable `count` to specify the number of samples to generate per label, with a generation quantity of 100 samples per label. - The `labels` list, which contains all labels, has been previously defined. Calculate the total number of samples, `total_samples`. 3. **Shared Progress Counter and Lock**(2 Pts): - Create a multi-process shared variable `progress` (using `Value`) to track the total number of generated samples. - Create a `Lock` object to manage access to shared resources. 4. **Label Splitting**(1 Pt): - Define the variable `num_processes` to indicate the number of processes. Set it to the number of cores on your processor. - Split `labels` into `num_processes` chunks so that each process handles one chunk of labels. 5. **Multi-process Implementation**(2 Pts): - Create a `Process` instance for each chunk of labels and call the `process_labels` function to handle that chunk. Pass `font_files`, `count`, `progress`, and `lock` as arguments to `process_labels`. - Start each process so they run in parallel. 6. **Progress Bar Implementation**(1 Pt): - Use `tqdm` to display the total progress of sample generation, updating once per second. - In a loop, check the status of each process and use the `progress` variable to update the `tqdm` progress bar until all processes finish. 7. **Wait for Processes to Finish**(1 Pt): - Use `join` to ensure that all processes complete before the code continues executing. 8. **Completion Message**(1 Pt): - After all processes are complete, print “All samples generated”. **Hints**: - Ensure that you pass the correct parameters to `process_labels` in each process. - Use `lock` to ensure thread-safe progress updates. - Try debugging and running the code to ensure that the progress bar and parallel processes display and execute correctly.这些要求,你可以给我一个最合适的代码,解决当前“子进程根本没有被成功创建或未实际运行 process_labels 函数”的问题吗?既然当前子进程对象被创建了,但其目标函数 process_labels 实际上从未被执行!  🔍 最可能原因:未正确设置 multiprocessing 启动方式 + 在 Jupyter 中直接运行多进程 这是最常见的“假启动”问题!你觉得该怎么改这个问题呢,可以给我合适的task1代码吗?注意,我没办法新创建.py文件,因为我们要求最终上传这个markdown文件。擅自利用新建的.py文件是不被允许的
11-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值